soracom 1.0.1
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 +7 -0
- data/.gitignore +35 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +47 -0
- data/LICENSE +22 -0
- data/LICENSE.txt +21 -0
- data/README.md +138 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/exe/soracom +8 -0
- data/lib/soracom/api_client.rb +60 -0
- data/lib/soracom/cli.rb +320 -0
- data/lib/soracom/client.rb +332 -0
- data/lib/soracom/event_handler.rb +44 -0
- data/lib/soracom/rest_client.rb +48 -0
- data/lib/soracom/subscriber.rb +17 -0
- data/lib/soracom/version.rb +4 -0
- data/lib/soracom.rb +8 -0
- data/samples/test.rb +24 -0
- data/soracom.gemspec +29 -0
- metadata +152 -0
data/lib/soracom/cli.rb
ADDED
@@ -0,0 +1,320 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require 'open-uri'
|
5
|
+
|
6
|
+
module SoracomCli
|
7
|
+
# SIM related commands
|
8
|
+
class Subscriber < Thor
|
9
|
+
desc 'list', 'list Subscriber(SIM)s'
|
10
|
+
option :limit, type: :numeric, required: false, desc: 'max number of result(default:1024)'
|
11
|
+
option :filter, type: :hash, required: false, desc: 'ex) --filter key:imsi value:001010000000001 / --filter key:tagname value:tagvalue'
|
12
|
+
def list
|
13
|
+
client = Soracom::Client.new
|
14
|
+
sims = client.list_subscribers(Hash[options.map { |k, v| [k.to_sym, v] }])
|
15
|
+
puts JSON.pretty_generate(sims)
|
16
|
+
end
|
17
|
+
|
18
|
+
desc 'register', 'register Subscriber(SIM)'
|
19
|
+
option :registration_secret, type: :string, required: true, desc: 'Registration Secret, 5 digits'
|
20
|
+
option :imsi, type: :string, required: true, desc: 'SIM unique ID, 15 digits'
|
21
|
+
option :type, type: :string, desc: 'default plan type'
|
22
|
+
option :tags, type: :hash, desc: 'tag as hash i.e. --tags name:"foo" group:"bar"'
|
23
|
+
def register
|
24
|
+
client = Soracom::Client.new
|
25
|
+
puts JSON.pretty_generate(client.register_subscriber(Hash[options.map { |k, v| [k.to_sym, v] }]))
|
26
|
+
end
|
27
|
+
|
28
|
+
desc 'activate', 'activate Subscriber(SIM)s'
|
29
|
+
option :imsi, type: :array, required: true
|
30
|
+
def activate
|
31
|
+
client = Soracom::Client.new
|
32
|
+
puts JSON.pretty_generate(client.activate_subscriber(options[:imsi]))
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'deactivate', 'deactivate Subscriber(SIM)s'
|
36
|
+
option :imsi, type: :array, required: true
|
37
|
+
def deactivate
|
38
|
+
client = Soracom::Client.new
|
39
|
+
puts JSON.pretty_generate(client.deactivate_subscriber(options[:imsi]))
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'terminate', 'terminate Subscriber(SIM)s'
|
43
|
+
option :imsi, type: :array, required: true
|
44
|
+
option :confirm, type: :string
|
45
|
+
def terminate
|
46
|
+
abort 'You may not revert terminate opereation. Please add "--confirm YES" if you are sure.' if options[:confirm] != 'YES'
|
47
|
+
client = Soracom::Client.new
|
48
|
+
puts JSON.pretty_generate(client.terminate_subscriber(options[:imsi]))
|
49
|
+
end
|
50
|
+
|
51
|
+
desc 'enable_termination', 'enable termination of Subscriber(SIM)s'
|
52
|
+
option :imsi, type: :array, required: true
|
53
|
+
def enable_termination
|
54
|
+
client = Soracom::Client.new
|
55
|
+
puts JSON.pretty_generate(client.enable_termination(options[:imsi]))
|
56
|
+
end
|
57
|
+
|
58
|
+
desc 'disable_termination', 'disable termination of Subscriber(SIM)s'
|
59
|
+
option :imsi, type: :array, required: true
|
60
|
+
def disable_termination
|
61
|
+
client = Soracom::Client.new
|
62
|
+
puts JSON.pretty_generate(client.disable_termination(options[:imsi]))
|
63
|
+
end
|
64
|
+
|
65
|
+
desc 'update_tags', 'add or update tags for Subscriber(SIM)s'
|
66
|
+
option :imsi, type: :array, required: true
|
67
|
+
option :tags, type: :hash, required: true
|
68
|
+
def update_tags
|
69
|
+
client = Soracom::Client.new
|
70
|
+
puts JSON.pretty_generate(client.update_subscriber_tags(options[:imsi], options[:tags]))
|
71
|
+
end
|
72
|
+
|
73
|
+
desc 'delete_tag', 'delete tag for Subscriber(SIM)s'
|
74
|
+
option :imsi, type: :array, required: true
|
75
|
+
option :tag_name, type: :string, required: true
|
76
|
+
def delete_tag
|
77
|
+
client = Soracom::Client.new
|
78
|
+
puts JSON.pretty_generate(client.delete_subscriber_tag(options[:imsi], options[:tag_name]))
|
79
|
+
end
|
80
|
+
|
81
|
+
desc 'update_speed_class', 'change speed class for Subscriber(SIM)s'
|
82
|
+
option :imsi, type: :array, required: true
|
83
|
+
option :speed_class, type: :string, required: true
|
84
|
+
def update_speed_class
|
85
|
+
client = Soracom::Client.new
|
86
|
+
puts JSON.pretty_generate(client.update_subscriber_speed_class(options[:imsi], options[:speed_class]))
|
87
|
+
end
|
88
|
+
|
89
|
+
desc 'set_expiry_time', 'update expiry time of Subscriber(SIM)s'
|
90
|
+
option :imsi, type: :array, required: true
|
91
|
+
option :expiry_time, type: :numeric, required: true
|
92
|
+
def set_expiry_time
|
93
|
+
client = Soracom::Client.new
|
94
|
+
puts JSON.pretty_generate(client.set_expiry_time(options[:imsi], options[:expiry_time]))
|
95
|
+
end
|
96
|
+
|
97
|
+
desc 'unset_expiry_time', 'delete expiry time of Subscriber(SIM)s'
|
98
|
+
option :imsi, type: :array, required: true
|
99
|
+
def unset_expiry_time
|
100
|
+
client = Soracom::Client.new
|
101
|
+
puts JSON.pretty_generate(client.unset_expiry_time(options[:imsi]))
|
102
|
+
end
|
103
|
+
|
104
|
+
desc 'set_group', 'set group of Subscriber(SIM)'
|
105
|
+
option :imsi, type: :string, required: true
|
106
|
+
option :group_id, type: :string, required: true
|
107
|
+
def set_group
|
108
|
+
client = Soracom::Client.new
|
109
|
+
puts JSON.pretty_generate(client.set_group(options[:imsi], options[:group_id]))
|
110
|
+
end
|
111
|
+
|
112
|
+
desc 'unset_group', 'unset group of Subscriber(SIM)'
|
113
|
+
option :imsi, type: :string, required: true
|
114
|
+
def unset_group
|
115
|
+
client = Soracom::Client.new
|
116
|
+
puts JSON.pretty_generate(client.unset_group(options[:imsi]))
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Group related commands
|
121
|
+
class Group < Thor
|
122
|
+
desc 'list', 'list groups'
|
123
|
+
option :group_id, type: :string, desc: 'group ID'
|
124
|
+
def list
|
125
|
+
client = Soracom::Client.new
|
126
|
+
puts JSON.pretty_generate(client.list_groups(options.group_id))
|
127
|
+
end
|
128
|
+
|
129
|
+
desc 'list_subscribers', 'list subscriber in a group'
|
130
|
+
option :group_id, type: :string, required:true, desc: 'group ID'
|
131
|
+
def list_subscribers
|
132
|
+
client = Soracom::Client.new
|
133
|
+
puts JSON.pretty_generate(client.list_subscribers_in_group(options.group_id))
|
134
|
+
end
|
135
|
+
|
136
|
+
desc 'create', 'create group'
|
137
|
+
option :parameters, type: :hash, desc: 'group parameters'
|
138
|
+
option :tags, type: :hash, desc: 'group tags'
|
139
|
+
def create
|
140
|
+
client = Soracom::Client.new
|
141
|
+
puts JSON.pretty_generate(client.create_group(options.parameters, options.tags))
|
142
|
+
end
|
143
|
+
|
144
|
+
desc 'delete_group', 'delete a group'
|
145
|
+
option :group_id, type: :string, required:true, desc: 'group ID'
|
146
|
+
def delete
|
147
|
+
client = Soracom::Client.new
|
148
|
+
puts JSON.pretty_generate(client.delete_group(options.group_id))
|
149
|
+
end
|
150
|
+
|
151
|
+
desc 'update_configuration', 'update configuration parameter'
|
152
|
+
option :group_id, type: :string, required:true, desc: 'group ID'
|
153
|
+
option :namespace, type: :string, required:true, desc: 'namespace of the parameter'
|
154
|
+
option :params, type: :string, required:true, desc: 'JSON string of the configuration parameter'
|
155
|
+
def update_configuration
|
156
|
+
client = Soracom::Client.new
|
157
|
+
puts JSON.pretty_generate(client.update_group_configuration(options.group_id, options.namespace, options.params))
|
158
|
+
end
|
159
|
+
|
160
|
+
desc 'delete_configuration', 'delete configuration parameter'
|
161
|
+
option :group_id, type: :string, required:true, desc: 'group ID'
|
162
|
+
option :namespace, type: :string, required:true, desc: 'namespace of the parameter'
|
163
|
+
option :name, type: :string, required:true, desc: 'name of configuration parameter to delete'
|
164
|
+
def delete_configuration
|
165
|
+
client = Soracom::Client.new
|
166
|
+
puts JSON.pretty_generate(client.delete_group_configuration(options.group_id, options.namespace, options.name))
|
167
|
+
end
|
168
|
+
|
169
|
+
desc 'update_tags', 'update group tags'
|
170
|
+
option :group_id, type: :string, required:true, desc: 'group ID'
|
171
|
+
option :tags, type: :string, required:true, desc: 'JSON string of tags i.e. [{"tagName":"name","tagValue":"new group name"}]'
|
172
|
+
def update_tags
|
173
|
+
client = Soracom::Client.new
|
174
|
+
puts JSON.pretty_generate(client.update_group_tags(options.group_id, options.tags))
|
175
|
+
end
|
176
|
+
|
177
|
+
desc 'delete_tag', 'delete group tag'
|
178
|
+
option :group_id, type: :string, required:true, desc: 'group ID'
|
179
|
+
option :name, type: :string, required:true, desc: 'tag name to delete'
|
180
|
+
def delete_tag
|
181
|
+
client = Soracom::Client.new
|
182
|
+
puts JSON.pretty_generate(client.delete_group_tags(options.group_id, options.name))
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# EventHandler related commands
|
187
|
+
class EventHandler < Thor
|
188
|
+
desc 'list', 'list groups'
|
189
|
+
option :handler_id, type: :string, desc: 'group ID'
|
190
|
+
option :imsi, type: :string, desc: 'SIM unique ID, 15 digits'
|
191
|
+
option :target, type: :string, desc: 'target can be operator/imsi/tag'
|
192
|
+
def list
|
193
|
+
client = Soracom::Client.new
|
194
|
+
puts JSON.pretty_generate(client.list_event_handlers(Hash[options.map { |k, v| [k.to_sym, v] }]))
|
195
|
+
end
|
196
|
+
|
197
|
+
desc 'create', 'create event handler'
|
198
|
+
option :req, type: :string, desc: 'JSON string of event handler configuration'
|
199
|
+
def create
|
200
|
+
client = Soracom::Client.new
|
201
|
+
puts JSON.pretty_generate(client.create_event_handler(options.req))
|
202
|
+
end
|
203
|
+
|
204
|
+
desc 'delete', 'delete event handler'
|
205
|
+
option :handler_id, type: :string, required:true, desc: 'Event Handler ID'
|
206
|
+
def delete
|
207
|
+
client = Soracom::Client.new
|
208
|
+
puts JSON.pretty_generate(client.delete_event_handler(options.handler_id))
|
209
|
+
end
|
210
|
+
|
211
|
+
desc 'update', 'update event handler configuration'
|
212
|
+
option :handler_id, type: :string, required:true, desc: 'Event Handler ID'
|
213
|
+
option :req, type: :string, desc: 'JSON string of event handler configuration'
|
214
|
+
def update
|
215
|
+
client = Soracom::Client.new
|
216
|
+
puts JSON.pretty_generate(client.update_event_handler(options.handler_id, options.req))
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# Stats related commands
|
221
|
+
class Stats < Thor
|
222
|
+
desc 'get_air_usage', 'get air usage per Subscriber(SIM)'
|
223
|
+
option :imsi, type: :string, required: true, desc: '15 digits SIM unique ID'
|
224
|
+
option :from, type: :numeric, required: false, desc: 'UNIX time in seconds when stat window begins'
|
225
|
+
option :to, type: :numeric, required: false, desc: 'UNIX time in seconds when stat window ends'
|
226
|
+
option :period, type: :string, required: false, desc: 'miniutes or day or month'
|
227
|
+
def get_air_usage
|
228
|
+
client = Soracom::Client.new
|
229
|
+
data = client.get_air_usage(Hash[options.map { |k, v| [k.to_sym, v] }])
|
230
|
+
puts JSON.pretty_generate(data)
|
231
|
+
end
|
232
|
+
|
233
|
+
desc 'get_beam_usage', 'get beam usage per Subscriber(SIM)'
|
234
|
+
option :imsi, type: :string, required: true, desc: '15 digits SIM unique ID'
|
235
|
+
option :from, type: :numeric, required: false, desc: 'UNIX time in seconds when stat window begins'
|
236
|
+
option :to, type: :numeric, required: false, desc: 'UNIX time in seconds when stat window ends'
|
237
|
+
option :period, type: :string, required: false, desc: 'miniutes or day or month'
|
238
|
+
def get_beam_usage
|
239
|
+
client = Soracom::Client.new
|
240
|
+
data = client.get_beam_usage(Hash[options.map { |k, v| [k.to_sym, v] }])
|
241
|
+
puts JSON.pretty_generate(data)
|
242
|
+
end
|
243
|
+
|
244
|
+
desc 'export_air_usage', 'export air usage for all Subscriber(SIM)s in csv format'
|
245
|
+
option :from, type: :numeric, required: false, desc: 'UNIX time in seconds when stat window begins'
|
246
|
+
option :to, type: :numeric, required: false, desc: 'UNIX time in seconds when stat window ends'
|
247
|
+
option :period, type: :string, required: false, desc: 'miniutes or day or month'
|
248
|
+
def export_air_usage
|
249
|
+
client = Soracom::Client.new
|
250
|
+
csv = client.export_air_usage(Hash[options.map { |k, v| [k.to_sym, v] }])
|
251
|
+
puts csv
|
252
|
+
end
|
253
|
+
|
254
|
+
desc 'export_beam_usage', 'export beam usage for all Subscriber(SIM)s in csv format'
|
255
|
+
option :from, type: :numeric, required: false, desc: 'UNIX time in seconds when stat window begins'
|
256
|
+
option :to, type: :numeric, required: false, desc: 'UNIX time in seconds when stat window ends'
|
257
|
+
option :period, type: :string, required: false, desc: 'miniutes or day or month'
|
258
|
+
def export_beam_usage
|
259
|
+
client = Soracom::Client.new
|
260
|
+
csv = client.export_beam_usage(Hash[options.map { |k, v| [k.to_sym, v] }])
|
261
|
+
puts csv
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
# Using Thor for CLI Implementation
|
266
|
+
class CLI < Thor
|
267
|
+
register(Subscriber, 'subscriber', 'subscriber <command>', 'Subscriber related operations')
|
268
|
+
register(Subscriber, 'sim', 'sim <command>', 'Subscriber related operations(alias)')
|
269
|
+
register(Group, 'group', 'group <command>', 'Group related operations')
|
270
|
+
register(EventHandler, 'event_handler', 'event_handler <command>', 'Event Handler related operations')
|
271
|
+
register(Stats, 'stats', 'stats <command>', 'Stats related operations')
|
272
|
+
|
273
|
+
desc 'auth', 'test authentication'
|
274
|
+
def auth
|
275
|
+
puts 'testing authentication...'
|
276
|
+
begin
|
277
|
+
client = Soracom::Client.new
|
278
|
+
puts <<EOS
|
279
|
+
authentication succeeded.
|
280
|
+
apiKey: #{client.api_key}
|
281
|
+
operatorId: #{client.operator_id}
|
282
|
+
EOS
|
283
|
+
rescue => evar
|
284
|
+
abort 'ERROR: ' + evar.to_s
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
desc 'support', 'open support site'
|
289
|
+
def support
|
290
|
+
client = Soracom::Client.new
|
291
|
+
url = client.get_support_url
|
292
|
+
system "open '#{url}' &> /dev/null || ( echo open following URL in your browser. ; echo '#{url}' )"
|
293
|
+
end
|
294
|
+
|
295
|
+
desc 'version', 'print version'
|
296
|
+
def version
|
297
|
+
puts "Soracom API tool v#{Soracom::VERSION}"
|
298
|
+
end
|
299
|
+
|
300
|
+
desc 'complete', 'command list for shell completion'
|
301
|
+
def complete
|
302
|
+
commands = CLI.commands.select { |k, _v| k != 'complete' }.map { |k, _v| k }.join(' ')
|
303
|
+
subcommands = {}
|
304
|
+
CLI.subcommand_classes.each { |k, v| subcommands[k] = v.commands.map { |k2, _v2| k2 } }
|
305
|
+
subcommands_string = subcommands.map do |k, v|
|
306
|
+
<<EOS
|
307
|
+
[ "$3" = "#{k}" ] && COMPREPLY=( $( compgen -W "#{v.join(' ')}" ${COMP_WORDS[COMP_CWORD]} ) )
|
308
|
+
EOS
|
309
|
+
end.join
|
310
|
+
print <<EOS
|
311
|
+
_soracom()
|
312
|
+
{
|
313
|
+
[ "$3" = "soracom" ] && COMPREPLY=( $( compgen -W "#{commands}" ${COMP_WORDS[COMP_CWORD]} ) )
|
314
|
+
#{subcommands_string}
|
315
|
+
}
|
316
|
+
complete -F _soracom soracom
|
317
|
+
EOS
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
@@ -0,0 +1,332 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'json'
|
4
|
+
require 'base64'
|
5
|
+
require 'ostruct'
|
6
|
+
require 'logger'
|
7
|
+
|
8
|
+
# SORACOM gem implementation
|
9
|
+
module Soracom
|
10
|
+
API_BASE_URL = 'https://api.soracom.io/v1'
|
11
|
+
# Soracom API Client
|
12
|
+
class Client
|
13
|
+
# 設定されなかった場合には、環境変数から認証情報を取得
|
14
|
+
def initialize(email:ENV['SORACOM_EMAIL'], password:ENV['SORACOM_PASSWORD'], endpoint:ENV['SORACOM_ENDPOINT'])
|
15
|
+
@log = Logger.new(STDERR)
|
16
|
+
@log.level = ENV['SORACOM_DEBUG'] ? Logger::DEBUG : Logger::WARN
|
17
|
+
begin
|
18
|
+
if email && password
|
19
|
+
@auth = auth(email, password, endpoint)
|
20
|
+
else
|
21
|
+
fail 'Could not find any credentials(email & password)'
|
22
|
+
end
|
23
|
+
rescue => evar
|
24
|
+
abort 'ERROR: ' + evar.to_s
|
25
|
+
end
|
26
|
+
@api = Soracom::ApiClient.new(@auth, endpoint)
|
27
|
+
end
|
28
|
+
|
29
|
+
# 特定Operator下のSubscriber一覧を取
|
30
|
+
def list_subscribers(operatorId:@auth[:operatorId], limit:1024, filter:{})
|
31
|
+
filter = Hash[filter.map { |k, v| [k.to_sym, v] }]
|
32
|
+
if filter[:key].nil?
|
33
|
+
return @api.get(path: '/subscribers', params: { operatorId: operatorId, limit: limit })
|
34
|
+
end
|
35
|
+
|
36
|
+
# filterありの場合
|
37
|
+
case filter[:key]
|
38
|
+
when 'imsi'
|
39
|
+
[@api.get(path: "/subscribers/#{filter[:value]}", params: { operatorId: operatorId, limit: limit })]
|
40
|
+
when 'msisdn'
|
41
|
+
[@api.get(path: "/subscribers/msisdn/#{filter[:value]}", params: { operatorId: operatorId, limit: limit })]
|
42
|
+
when 'status'
|
43
|
+
@api.get(path: '/subscribers', params: { operatorId: operatorId, limit: limit, status_filter: filter[:value].gsub('|', '%7C') })
|
44
|
+
when 'speed_class'
|
45
|
+
@api.get(path: '/subscribers', params: { operatorId: operatorId, limit: limit, speed_class_filter: filter[:value] })
|
46
|
+
else
|
47
|
+
@api.get(path: '/subscribers', params: { operatorId: operatorId, limit: limit, tag_name: filter[:key], tag_value: filter[:value], tag_value_match_mode: filter[:mode] || 'exact' })
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def subscribers(operatorId:@auth[:operatorId], limit:1024, filter:{})
|
52
|
+
list_subscribers(operatorId: operatorId, limit: limit, filter: filter).map { |s| Soracom::Subscriber.new(s, self) }
|
53
|
+
end
|
54
|
+
|
55
|
+
# SIMの登録
|
56
|
+
def register_subscriber(imsi:nil, registration_secret:nil, groupId:nil, tags:{})
|
57
|
+
params = { registrationSecret: registration_secret, tags: tags }
|
58
|
+
params[groupId] = groupId if groupId
|
59
|
+
@api.post(path: "/subscribers/#{imsi}", payload: params)
|
60
|
+
end
|
61
|
+
|
62
|
+
# SIMの利用開始(再開)
|
63
|
+
def activate_subscriber(imsis)
|
64
|
+
threads = [], result = []
|
65
|
+
imsis.map do |imsi|
|
66
|
+
threads << Thread.new do
|
67
|
+
result << { 'imsi' => imsi }.merge(@api.post(path: "/subscribers/#{imsi}/activate"))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
threads.each(&:join)
|
71
|
+
result
|
72
|
+
end
|
73
|
+
|
74
|
+
# SIMの利用休止
|
75
|
+
def deactivate_subscriber(imsis)
|
76
|
+
threads = [], result = []
|
77
|
+
imsis.map do |imsi|
|
78
|
+
threads << Thread.new do
|
79
|
+
result << { 'imsi' => imsi }.merge(@api.post(path: "/subscribers/#{imsi}/deactivate"))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
threads.each(&:join)
|
83
|
+
result
|
84
|
+
end
|
85
|
+
|
86
|
+
# SIMの解約
|
87
|
+
def terminate_subscriber(imsis)
|
88
|
+
threads = [], result = []
|
89
|
+
imsis.map do |imsi|
|
90
|
+
threads << Thread.new do
|
91
|
+
result << { 'imsi' => imsi }.merge(@api.post(path: "/subscribers/#{imsi}/terminate"))
|
92
|
+
end
|
93
|
+
end
|
94
|
+
threads.each(&:join)
|
95
|
+
result
|
96
|
+
end
|
97
|
+
|
98
|
+
# 指定されたSubscriberをTerminate可能に設定する
|
99
|
+
def enable_termination(imsis)
|
100
|
+
threads = [], result = []
|
101
|
+
imsis.map do |imsi|
|
102
|
+
threads << Thread.new do
|
103
|
+
result << { 'imsi' => imsi }.merge(@api.post(path: "/subscribers/#{imsi}/enable_termination"))
|
104
|
+
end
|
105
|
+
end
|
106
|
+
threads.each(&:join)
|
107
|
+
result
|
108
|
+
end
|
109
|
+
|
110
|
+
# 指定されたSubscriberをTerminate不可能に設定する
|
111
|
+
def disable_termination(imsis)
|
112
|
+
threads = [], result = []
|
113
|
+
imsis.map do |imsi|
|
114
|
+
threads << Thread.new do
|
115
|
+
result << { 'imsi' => imsi }.merge(@api.post(path: "/subscribers/#{imsi}/disable_termination"))
|
116
|
+
end
|
117
|
+
end
|
118
|
+
threads.each(&:join)
|
119
|
+
p result
|
120
|
+
result
|
121
|
+
end
|
122
|
+
|
123
|
+
# タグの更新
|
124
|
+
def update_subscriber_tags(imsis, tags)
|
125
|
+
threads = [], result = []
|
126
|
+
imsis.map do |imsi|
|
127
|
+
threads << Thread.new do
|
128
|
+
result << { 'imsi' => imsi }.merge(@api.post(path: "/subscribers/#{imsi}/update_tags", payload: tags))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
threads.each(&:join)
|
132
|
+
result
|
133
|
+
end
|
134
|
+
|
135
|
+
# 指定タグの削除
|
136
|
+
def delete_subscriber_tag(imsis, tag_name)
|
137
|
+
threads = [], result = []
|
138
|
+
imsis.map do |imsi|
|
139
|
+
threads << Thread.new do
|
140
|
+
result << { 'imsi' => imsi }.merge(@api.delete(path: "/subscribers/#{imsi}/tags/#{tag_name}"))
|
141
|
+
end
|
142
|
+
end
|
143
|
+
threads.each(&:join)
|
144
|
+
result
|
145
|
+
end
|
146
|
+
|
147
|
+
# SIMのプラン変更
|
148
|
+
def update_subscriber_speed_class(imsis, speed_class)
|
149
|
+
imsis = [imsis] if imsis.class == String
|
150
|
+
threads = [], result = []
|
151
|
+
imsis.map do |imsi|
|
152
|
+
threads << Thread.new do
|
153
|
+
result << { 'imsi' => imsi }.merge(@api.post(path: "/subscribers/#{imsi}/update_speed_class", payload: { speedClass: speed_class }))
|
154
|
+
end
|
155
|
+
end
|
156
|
+
threads.each(&:join)
|
157
|
+
result
|
158
|
+
end
|
159
|
+
|
160
|
+
# SIMの有効期限設定
|
161
|
+
def set_expiry_time(imsis, expiry_time)
|
162
|
+
threads = [], result = []
|
163
|
+
imsis.map do |imsi|
|
164
|
+
threads << Thread.new do
|
165
|
+
result << { 'imsi' => imsi }.merge(@api.post(path: "/subscribers/#{imsi}/set_expiry_time", payload: { expiryTime: expiry_time }))
|
166
|
+
end
|
167
|
+
end
|
168
|
+
threads.each(&:join)
|
169
|
+
result
|
170
|
+
end
|
171
|
+
|
172
|
+
# SIMの有効期限設定を解除
|
173
|
+
def unset_expiry_time(imsis)
|
174
|
+
threads = [], result = []
|
175
|
+
imsis.map do |imsi|
|
176
|
+
threads << Thread.new do
|
177
|
+
result << { 'imsi' => imsi }.merge(@api.post(path: "/subscribers/#{imsi}/unset_expiry_time"))
|
178
|
+
end
|
179
|
+
end
|
180
|
+
threads.each(&:join)
|
181
|
+
result
|
182
|
+
end
|
183
|
+
|
184
|
+
# SIMの所属Groupを指定あるいは上書き変更
|
185
|
+
def set_group(imsi, group_id)
|
186
|
+
@api.post(path: "/subscribers/#{imsi}/set_group", payload: { groupId: group_id })
|
187
|
+
end
|
188
|
+
|
189
|
+
# SIMの所属Groupを指定を解除
|
190
|
+
def unset_group(imsi)
|
191
|
+
@api.post(path: "/subscribers/#{imsi}/unset_group")
|
192
|
+
end
|
193
|
+
|
194
|
+
# SIMグループの一覧を取得
|
195
|
+
def list_groups(group_id)
|
196
|
+
if group_id
|
197
|
+
[ @api.get(path: "/groups/#{group_id}") ]
|
198
|
+
else
|
199
|
+
@api.get(path: '/groups')
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
# SIMグループを新規作成
|
204
|
+
def create_group(parameters:nil, tags:nil)
|
205
|
+
payload = {}
|
206
|
+
payload['parameters'] = parameters if parameters
|
207
|
+
payload['tags'] = tags if tags
|
208
|
+
@api.post(path: '/groups', payload: payload)
|
209
|
+
end
|
210
|
+
|
211
|
+
# SIMグループの削除
|
212
|
+
def delete_group(group_id)
|
213
|
+
@api.delete(path: "/groups/#{group_id}")
|
214
|
+
end
|
215
|
+
|
216
|
+
# SIMグループの削除
|
217
|
+
def list_subscribers_in_group(group_id)
|
218
|
+
@api.get(path: "/groups/#{group_id}/subscribers")
|
219
|
+
end
|
220
|
+
|
221
|
+
# コンフィグパラメータの更新
|
222
|
+
def update_group_configuration(group_id, namespace, params)
|
223
|
+
@api.put(path: "/groups/#{group_id}/configuration/#{namespace}", payload: params)
|
224
|
+
end
|
225
|
+
|
226
|
+
# コンフィグパラメータ内の設定を削除
|
227
|
+
def delete_group_configuration(group_id, namespace, name)
|
228
|
+
@api.delete(path: "/groups/#{group_id}/configuration/#{namespace}/#{name}")
|
229
|
+
end
|
230
|
+
|
231
|
+
# コンフィグパラメータの更新
|
232
|
+
def update_group_tags(group_id, tags = {})
|
233
|
+
@api.put(path: "/groups/#{group_id}/tags", payload: tags)
|
234
|
+
end
|
235
|
+
|
236
|
+
# コンフィグパラメータ内の設定を削除
|
237
|
+
def delete_group_tags(group_id, name)
|
238
|
+
@api.delete(path: "/groups/#{group_id}/tags/#{name}")
|
239
|
+
end
|
240
|
+
|
241
|
+
# イベントハンドラーの一覧を得る
|
242
|
+
def list_event_handlers(handler_id:nil, target:nil, imsi:nil)
|
243
|
+
if handler_id
|
244
|
+
[@api.get(path: "/event_handlers/#{handler_id}")]
|
245
|
+
elsif imsi
|
246
|
+
@api.get(path: "/event_handlers/subscribers/#{imsi}")
|
247
|
+
elsif target # target is one of imsi/operator/tag
|
248
|
+
@api.get(path: '/event_handlers', params: { target: target })
|
249
|
+
else
|
250
|
+
@api.get(path: "/event_handlers")
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
# イベントハンドラーを新規作成する
|
255
|
+
def create_event_handler(req)
|
256
|
+
@api.post(path: '/event_handlers', payload: req)
|
257
|
+
end
|
258
|
+
|
259
|
+
# イベントハンドラーの情報を得る
|
260
|
+
def get_event_handler(handler_id)
|
261
|
+
@api.get(path: "/event_handlers/#{handler_id}")
|
262
|
+
end
|
263
|
+
|
264
|
+
# イベントハンドラーを削除する
|
265
|
+
def delete_event_handler(handler_id)
|
266
|
+
@api.delete(path: "/event_handlers/#{handler_id}")
|
267
|
+
end
|
268
|
+
|
269
|
+
# イベントハンドラーを更新する
|
270
|
+
def update_event_handler(handler_id, params)
|
271
|
+
@api.put(path: "/event_handlers/#{handler_id}", payload: params)
|
272
|
+
end
|
273
|
+
|
274
|
+
# Subscriber毎のAir使用状況を得る(デフォルトでは直近1日)
|
275
|
+
def get_air_usage(imsi:nil, from:(Time.now.to_i - 24 * 60 * 60), to:Time.now.to_i, period:'minutes')
|
276
|
+
@api.get(path: "/stats/air/subscribers/#{imsi}", params: { from: from, to: to, period: period })
|
277
|
+
end
|
278
|
+
|
279
|
+
# Subscriber毎のBeam使用状況を得る(デフォルトでは直近1日)
|
280
|
+
def get_beam_usage(imsi:nil, from:(Time.now.to_i - 24 * 60 * 60), to:Time.now.to_i, period:'minutes')
|
281
|
+
@api.get(path: "/stats/beam/subscribers/#{imsi}", params: { from: from, to: to, period: period })
|
282
|
+
end
|
283
|
+
|
284
|
+
# Operator配下の全Subscriberに関するAir使用状況をダウンロードする(デフォルトでは今月)
|
285
|
+
def export_air_usage(operator_id:@auth[:operatorId] , from:Time.parse("#{Time.now.year}-#{Time.now.month}-#{Time.now.day}").to_i, to:Time.now.to_i, period:'day')
|
286
|
+
res = @api.post(path: "/stats/air/operators/#{operator_id}/export", payload: { from: from, to: to, period: period })
|
287
|
+
open(res['url']).read
|
288
|
+
end
|
289
|
+
|
290
|
+
# Operator配下の全Subscriberに関するBeam使用状況をダウンロードする(デフォルトでは今月)
|
291
|
+
def export_beam_usage(operator_id:@auth[:operatorId] , from:Time.parse("#{Time.now.year}-#{Time.now.month}-#{Time.now.day}").to_i, to:Time.now.to_i, period:'day')
|
292
|
+
res = @api.post(path: "/stats/beam/operators/#{operator_id}/export", payload: { from: from, to: to, period: period })
|
293
|
+
open(res['url']).read
|
294
|
+
end
|
295
|
+
|
296
|
+
# サポートサイトのURLを取得
|
297
|
+
def get_support_url(return_to: 'https://soracom.zendesk.com/hc/ja/requests')
|
298
|
+
res = @api.post(path: "/operators/#{@auth[:operatorId]}/support/token")
|
299
|
+
"https://soracom.zendesk.com/access/jwt?jwt=#{res['token']}&return_to=#{return_to}"
|
300
|
+
end
|
301
|
+
|
302
|
+
# APIキーを取得
|
303
|
+
def api_key
|
304
|
+
@auth[:apiKey]
|
305
|
+
end
|
306
|
+
|
307
|
+
# オペレータIDを取得
|
308
|
+
def operator_id
|
309
|
+
@auth[:operatorId]
|
310
|
+
end
|
311
|
+
|
312
|
+
private
|
313
|
+
|
314
|
+
# authenticate by email and password
|
315
|
+
def auth(email, password, endpoint)
|
316
|
+
endpoint = API_BASE_URL if endpoint.nil?
|
317
|
+
res = RestClient.post endpoint + '/auth',
|
318
|
+
{ email: email, password: password },
|
319
|
+
'Content-Type' => 'application/json',
|
320
|
+
'Accept' => 'application/json'
|
321
|
+
result = JSON.parse(res.body)
|
322
|
+
fail result['message'] if res.code != '200'
|
323
|
+
Hash[JSON.parse(res.body).map { |k, v| [k.to_sym, v] }]
|
324
|
+
end
|
325
|
+
|
326
|
+
def extract_jwt(jwt)
|
327
|
+
encoded = jwt.split('.')[1]
|
328
|
+
encoded += '=' * (4 - encoded.length % 4) # add padding(=) for Base64
|
329
|
+
Base64.decode64(encoded)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Soracom
|
2
|
+
# EventHandlerクラス
|
3
|
+
# 初期化方法1. 新規に作成
|
4
|
+
# 初期化方法2. 特定ハンドラのIDを指定して初期化({handlerId:HANDLERID}) → APIで現時点の内容を取得
|
5
|
+
# 初期化方法3. hashを指定して初期化(list_event_handlersの戻り値を利用など)
|
6
|
+
class EventHandler < OpenStruct
|
7
|
+
def initialize(hash = {}, client = Soracom::Client.new)
|
8
|
+
@log = Logger.new(STDERR)
|
9
|
+
@log.level = ENV['SORACOM_DEBUG'] ? Logger::DEBUG : Logger::WARN
|
10
|
+
if hash.keys.length == 0 # 新規作成
|
11
|
+
hash = Hash[%w(handlerId targetImsi targetOperatorId targetTag name description ruleConfig actionConfigList).map { |k| [k, nil] }]
|
12
|
+
end
|
13
|
+
if hash.keys.length == 1 && hash.keys[0] == 'handlerId' # IDのみを指定して作成
|
14
|
+
hash = client.list_event_handlers(handler_id: hash['handlerId'])[0]
|
15
|
+
end
|
16
|
+
super(hash)
|
17
|
+
@client = client
|
18
|
+
end
|
19
|
+
|
20
|
+
# 新規作成または更新用のpayloadをJSON形式で取得
|
21
|
+
def to_json
|
22
|
+
to_h.select { |k, v| true if !v.nil? && k != :handlerId }.to_json
|
23
|
+
end
|
24
|
+
|
25
|
+
# 現在の内容でEventHandlerを作成または更新
|
26
|
+
def save
|
27
|
+
result = validate
|
28
|
+
fail result unless result == true
|
29
|
+
@log.debug(to_json)
|
30
|
+
if handlerId
|
31
|
+
@client.update_event_handler(handlerId, to_json)
|
32
|
+
else
|
33
|
+
@client.create_event_handler(to_json)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate
|
38
|
+
return 'No target is defined' if [targetImsi, targetOperatorId, targetTag].compact.length == 0
|
39
|
+
return 'No rule is defined' if ruleConfig.nil? || ruleConfig.length == 0
|
40
|
+
return 'No action is defined' if actionConfigList.nil? || actionConfigList.length == 0
|
41
|
+
true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|