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.
@@ -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