openc3 5.5.2 → 5.6.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.
Potentially problematic release.
This version of openc3 might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/bin/openc3cli +167 -69
- data/data/config/_interfaces.yaml +1 -6
- data/data/config/interface_modifiers.yaml +55 -4
- data/data/config/microservice.yaml +30 -3
- data/ext/openc3/ext/crc/crc.c +82 -1
- data/lib/openc3/api/cmd_api.rb +19 -7
- data/lib/openc3/api/tlm_api.rb +13 -12
- data/lib/openc3/bridge/bridge_config.rb +4 -4
- data/lib/openc3/config/config_parser.rb +1 -0
- data/lib/openc3/conversions/unix_time_conversion.rb +3 -1
- data/lib/openc3/ext/.keep +0 -0
- data/lib/openc3/interfaces/interface.rb +54 -26
- data/lib/openc3/interfaces/serial_interface.rb +4 -5
- data/lib/openc3/interfaces/simulated_target_interface.rb +4 -4
- data/lib/openc3/interfaces/stream_interface.rb +2 -2
- data/lib/openc3/interfaces/tcpip_client_interface.rb +4 -3
- data/lib/openc3/interfaces/tcpip_server_interface.rb +18 -19
- data/lib/openc3/interfaces/udp_interface.rb +10 -4
- data/lib/openc3/io/json_api.rb +72 -0
- data/lib/openc3/io/serial_driver.rb +4 -5
- data/lib/openc3/logs/buffered_packet_log_writer.rb +2 -4
- data/lib/openc3/logs/log_writer.rb +9 -8
- data/lib/openc3/logs/packet_log_reader.rb +8 -1
- data/lib/openc3/logs/packet_log_writer.rb +3 -4
- data/lib/openc3/logs/stream_log.rb +116 -0
- data/lib/openc3/logs/stream_log_pair.rb +70 -0
- data/lib/openc3/microservices/cleanup_microservice.rb +1 -1
- data/lib/openc3/microservices/decom_microservice.rb +17 -2
- data/lib/openc3/microservices/interface_decom_common.rb +42 -0
- data/lib/openc3/microservices/interface_microservice.rb +24 -17
- data/lib/openc3/microservices/router_microservice.rb +46 -4
- data/lib/openc3/migrations/20221202214600_add_target_names.rb +1 -1
- data/lib/openc3/migrations/20230319154100_log_stream.rb +40 -0
- data/lib/openc3/migrations/20230413101100_remove_log.rb +30 -0
- data/lib/openc3/models/gem_model.rb +2 -2
- data/lib/openc3/models/interface_model.rb +13 -14
- data/lib/openc3/models/metadata_model.rb +1 -1
- data/lib/openc3/models/note_model.rb +1 -1
- data/lib/openc3/models/plugin_model.rb +3 -2
- data/lib/openc3/operators/operator.rb +2 -0
- data/lib/openc3/packets/commands.rb +2 -0
- data/lib/openc3/packets/packet_config.rb +3 -2
- data/lib/openc3/packets/parsers/xtce_converter.rb +2 -1
- data/lib/openc3/script/gems.rb +125 -0
- data/lib/openc3/script/plugins.rb +186 -0
- data/lib/openc3/script/screen.rb +119 -0
- data/lib/openc3/script/script.rb +3 -0
- data/lib/openc3/script/script_runner.rb +19 -8
- data/lib/openc3/script/suite_results.rb +2 -2
- data/lib/openc3/script/web_socket_api.rb +5 -1
- data/lib/openc3/streams/serial_stream.rb +14 -11
- data/lib/openc3/streams/tcpip_client_stream.rb +5 -2
- data/lib/openc3/streams/tcpip_socket_stream.rb +37 -71
- data/lib/openc3/streams/web_socket_client_stream.rb +5 -3
- data/lib/openc3/system/system.rb +2 -0
- data/lib/openc3/topics/interface_topic.rb +13 -4
- data/lib/openc3/topics/router_topic.rb +6 -6
- data/lib/openc3/topics/telemetry_decom_topic.rb +10 -1
- data/lib/openc3/utilities/bucket_utilities.rb +12 -5
- data/lib/openc3/utilities/cli_generator.rb +56 -4
- data/lib/openc3/utilities/crc.rb +42 -7
- data/lib/openc3/utilities/process_manager.rb +3 -1
- data/lib/openc3/utilities/ruby_lex_utils.rb +265 -504
- data/lib/openc3/version.rb +6 -6
- data/templates/conversion/conversion.rb +10 -2
- data/templates/microservice/microservices/TEMPLATE/microservice.rb +1 -1
- data/templates/plugin/Rakefile +8 -1
- data/templates/widget/.browserslistrc +16 -0
- data/templates/widget/.eslintrc.js +43 -0
- data/templates/widget/.nycrc +3 -0
- data/templates/widget/.prettierrc.js +5 -0
- data/templates/widget/LICENSE.txt +20 -0
- data/templates/widget/Rakefile +24 -0
- data/templates/widget/babel.config.json +11 -0
- data/templates/widget/package.json +35 -0
- data/templates/widget/src/Widget.vue +46 -0
- data/templates/widget/vue.config.js +25 -0
- data/templates/widget/yarn.lock +8938 -0
- metadata +23 -4
- data/lib/openc3/io/raw_logger.rb +0 -170
- data/lib/openc3/io/raw_logger_pair.rb +0 -80
@@ -28,7 +28,7 @@ require 'rubygems'
|
|
28
28
|
require 'rubygems/uninstaller'
|
29
29
|
require 'tempfile'
|
30
30
|
require 'openc3/utilities/process_manager'
|
31
|
-
require
|
31
|
+
require 'pathname'
|
32
32
|
|
33
33
|
module OpenC3
|
34
34
|
# This class acts like a Model but doesn't inherit from Model because it doesn't
|
@@ -55,7 +55,7 @@ module OpenC3
|
|
55
55
|
if gem_install
|
56
56
|
Logger.info "Installing gem: #{gem_filename}"
|
57
57
|
result = OpenC3::ProcessManager.instance.spawn(["ruby", "/openc3/bin/openc3cli", "geminstall", gem_filename, scope], "gem_install", gem_filename, Time.now + 3600.0, scope: scope)
|
58
|
-
return result
|
58
|
+
return result.name
|
59
59
|
end
|
60
60
|
else
|
61
61
|
message = "Gem file #{gem_file_path} does not exist!"
|
@@ -14,7 +14,7 @@
|
|
14
14
|
# GNU Affero General Public License for more details.
|
15
15
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
|
-
# All changes Copyright
|
17
|
+
# All changes Copyright 2023, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
20
|
# This file may also be used under the terms of a commercial license
|
@@ -41,8 +41,7 @@ module OpenC3
|
|
41
41
|
attr_accessor :secret_options
|
42
42
|
attr_accessor :protocols
|
43
43
|
attr_accessor :interfaces
|
44
|
-
attr_accessor :
|
45
|
-
attr_accessor :log_raw
|
44
|
+
attr_accessor :log_stream
|
46
45
|
attr_accessor :needs_dependencies
|
47
46
|
attr_accessor :secrets
|
48
47
|
|
@@ -105,8 +104,7 @@ module OpenC3
|
|
105
104
|
options: [],
|
106
105
|
secret_options: [],
|
107
106
|
protocols: [],
|
108
|
-
|
109
|
-
log_raw: false,
|
107
|
+
log_stream: nil,
|
110
108
|
updated_at: nil,
|
111
109
|
plugin: nil,
|
112
110
|
needs_dependencies: false,
|
@@ -129,8 +127,7 @@ module OpenC3
|
|
129
127
|
@options = options
|
130
128
|
@secret_options = secret_options
|
131
129
|
@protocols = protocols
|
132
|
-
@
|
133
|
-
@log_raw = log_raw
|
130
|
+
@log_stream = log_stream
|
134
131
|
@needs_dependencies = needs_dependencies
|
135
132
|
@secrets = secrets
|
136
133
|
end
|
@@ -165,6 +162,10 @@ module OpenC3
|
|
165
162
|
klass = OpenC3.require_class(protocol[1])
|
166
163
|
interface_or_router.add_protocol(klass, protocol[2..-1], protocol[0].upcase.intern)
|
167
164
|
end
|
165
|
+
if @log_stream
|
166
|
+
interface_or_router.stream_log_pair = StreamLogPair.new(interface_or_router.name, @log_stream)
|
167
|
+
interface_or_router.start_raw_logging
|
168
|
+
end
|
168
169
|
interface_or_router
|
169
170
|
end
|
170
171
|
|
@@ -182,8 +183,7 @@ module OpenC3
|
|
182
183
|
'options' => @options,
|
183
184
|
'secret_options' => @secret_options,
|
184
185
|
'protocols' => @protocols,
|
185
|
-
'
|
186
|
-
'log_raw' => @log_raw,
|
186
|
+
'log_stream' => @log_stream,
|
187
187
|
'plugin' => @plugin,
|
188
188
|
'needs_dependencies' => @needs_dependencies,
|
189
189
|
'secrets' => @secrets.as_json(*a),
|
@@ -249,12 +249,11 @@ module OpenC3
|
|
249
249
|
@protocols << parameters.dup
|
250
250
|
|
251
251
|
when 'DONT_LOG'
|
252
|
-
|
253
|
-
@log = false
|
252
|
+
Logger.warn "DONT_LOG is deprecated and does nothing."
|
254
253
|
|
255
|
-
when 'LOG_RAW'
|
256
|
-
parser.verify_num_parameters(0,
|
257
|
-
@
|
254
|
+
when 'LOG_STREAM', 'LOG_RAW'
|
255
|
+
parser.verify_num_parameters(0, nil, "#{keyword} <Log Stream Class File (optional)> <Log Stream Parameters (optional)>")
|
256
|
+
@log_stream = parameters.dup # Even if it is empty we copy it to set it as not nil
|
258
257
|
|
259
258
|
when 'SECRET'
|
260
259
|
parser.verify_num_parameters(3, 5, "#{keyword} <Secret Type: ENV or FILE> <Secret Name> <Environment Variable Name or File Path> <Option Name (Optional)> <Secret Store Name (Optional)>")
|
@@ -69,7 +69,7 @@ module OpenC3
|
|
69
69
|
if @color.nil?
|
70
70
|
@color = '#%06x' % (rand * 0xffffff)
|
71
71
|
end
|
72
|
-
unless @color =~
|
72
|
+
unless @color =~ /#?([0-9a-fA-F]{6})/
|
73
73
|
raise SortedInputError.new "invalid color, must be in hex format, e.g. #FF0000"
|
74
74
|
end
|
75
75
|
@color = "##{@color}" unless @color.start_with?('#')
|
@@ -78,7 +78,7 @@ module OpenC3
|
|
78
78
|
if @color.nil?
|
79
79
|
@color = '#%06x' % (rand * 0xffffff)
|
80
80
|
end
|
81
|
-
unless @color =~
|
81
|
+
unless @color =~ /#?([0-9a-fA-F]{6})/
|
82
82
|
raise SortedInputError.new "invalid color, must be in hex format, e.g. #FF0000"
|
83
83
|
end
|
84
84
|
@color = "##{@color}" unless @color.start_with?('#')
|
@@ -36,6 +36,7 @@ require 'openc3/models/widget_model'
|
|
36
36
|
require 'openc3/models/microservice_model'
|
37
37
|
require 'tmpdir'
|
38
38
|
require 'tempfile'
|
39
|
+
require 'fileutils'
|
39
40
|
|
40
41
|
module OpenC3
|
41
42
|
# Represents a OpenC3 plugin that can consist of targets, interfaces, routers
|
@@ -155,7 +156,7 @@ module OpenC3
|
|
155
156
|
end
|
156
157
|
|
157
158
|
# Actually install the gem now (slow)
|
158
|
-
OpenC3::GemModel.install(gem_file_path, scope: scope)
|
159
|
+
OpenC3::GemModel.install(gem_file_path, scope: scope) unless validate_only
|
159
160
|
|
160
161
|
# Extract gem contents
|
161
162
|
gem_path = File.join(temp_dir, "gem")
|
@@ -284,7 +285,7 @@ module OpenC3
|
|
284
285
|
microservice_count += 1
|
285
286
|
end
|
286
287
|
# Wait for the operator to wake up and remove the microservice processes
|
287
|
-
sleep
|
288
|
+
sleep 15 if microservice_count > 0 # Cycle time 5s times 2 plus 5s wait for soft stop and then hard stop
|
288
289
|
# Remove all the other models now that the processes have stopped
|
289
290
|
# Save TargetModel for last as it has the most to cleanup
|
290
291
|
[InterfaceModel, RouterModel, ToolModel, WidgetModel, TargetModel].each do |model|
|
@@ -83,6 +83,7 @@ module OpenC3
|
|
83
83
|
attr_accessor :new_temp_dir
|
84
84
|
attr_reader :temp_dir
|
85
85
|
attr_reader :scope
|
86
|
+
attr_reader :name
|
86
87
|
|
87
88
|
def self.setup
|
88
89
|
# Perform any setup steps necessary
|
@@ -139,6 +140,7 @@ module OpenC3
|
|
139
140
|
@process.io.stdout = OperatorProcessIO.new('microservice-stdout')
|
140
141
|
@process.io.stderr = OperatorProcessIO.new('microservice-stderr')
|
141
142
|
@process.start
|
143
|
+
@name = "#{Socket.gethostname}__#{@process.pid}"
|
142
144
|
end
|
143
145
|
|
144
146
|
def alive?
|
@@ -205,6 +205,8 @@ module OpenC3
|
|
205
205
|
else
|
206
206
|
output_string = 'cmd("'
|
207
207
|
end
|
208
|
+
target_name = 'UNKNOWN' unless target_name
|
209
|
+
cmd_name = 'UNKNOWN' unless cmd_name
|
208
210
|
output_string << target_name + ' ' + cmd_name
|
209
211
|
if cmd_params.nil? or cmd_params.empty?
|
210
212
|
output_string << '")'
|
@@ -17,7 +17,7 @@
|
|
17
17
|
# All changes Copyright 2022, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
|
-
# This file may also be used under the terms of a commercial license
|
20
|
+
# This file may also be used under the terms of a commercial license
|
21
21
|
# if purchased from OpenC3, Inc.
|
22
22
|
|
23
23
|
require 'openc3/config/config_parser'
|
@@ -35,6 +35,7 @@ require 'openc3/conversions'
|
|
35
35
|
require 'openc3/processors'
|
36
36
|
require 'nokogiri'
|
37
37
|
require 'ostruct'
|
38
|
+
require 'fileutils'
|
38
39
|
|
39
40
|
module OpenC3
|
40
41
|
# Reads a command or telemetry configuration file and builds a hash of packets.
|
@@ -523,7 +524,7 @@ module OpenC3
|
|
523
524
|
@converted_bit_size = nil
|
524
525
|
if params[0]
|
525
526
|
@converted_type = params[0].upcase.intern
|
526
|
-
raise parser.error("Invalid converted_type: #{@converted_type}.") unless [:INT, :UINT, :FLOAT, :STRING, :BLOCK].include? @converted_type
|
527
|
+
raise parser.error("Invalid converted_type: #{@converted_type}.") unless [:INT, :UINT, :FLOAT, :STRING, :BLOCK, :RUBY_TIME].include? @converted_type
|
527
528
|
end
|
528
529
|
@converted_bit_size = Integer(params[1]) if params[1]
|
529
530
|
if @converted_type.nil? or @converted_bit_size.nil?
|
@@ -17,11 +17,12 @@
|
|
17
17
|
# All changes Copyright 2022, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
|
-
# This file may also be used under the terms of a commercial license
|
20
|
+
# This file may also be used under the terms of a commercial license
|
21
21
|
# if purchased from OpenC3, Inc.
|
22
22
|
|
23
23
|
require 'nokogiri'
|
24
24
|
require 'openc3/packets/parsers/xtce_parser'
|
25
|
+
require 'fileutils'
|
25
26
|
|
26
27
|
module OpenC3
|
27
28
|
class XtceConverter
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2023 OpenC3, Inc.
|
4
|
+
# All Rights Reserved.
|
5
|
+
#
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
7
|
+
# under the terms of the GNU Affero General Public License
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# This file may also be used under the terms of a commercial license
|
17
|
+
# if purchased from OpenC3, Inc.
|
18
|
+
|
19
|
+
require 'openc3/script/plugins'
|
20
|
+
|
21
|
+
module OpenC3
|
22
|
+
module Script
|
23
|
+
private
|
24
|
+
|
25
|
+
def gem_list(scope: $openc3_scope)
|
26
|
+
response_body = nil
|
27
|
+
begin
|
28
|
+
endpoint = "/openc3-api/gems?scope=#{scope}"
|
29
|
+
uri = URI.parse($api_server.generate_url + endpoint)
|
30
|
+
auth = $api_server.generate_auth
|
31
|
+
|
32
|
+
request = Net::HTTP::Get.new(uri)
|
33
|
+
request['User-Agent'] = JsonDRbObject::USER_AGENT
|
34
|
+
request['Content-Type'] = 'application/json'
|
35
|
+
request['Authorization'] = auth.token
|
36
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
37
|
+
http.request(request) do |response|
|
38
|
+
response_body = response.body
|
39
|
+
response.value() # Raises an HTTP error if the response is not 2xx (success)
|
40
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
rescue => error
|
44
|
+
raise "gem_list failed due to #{error.formatted}\nResponse:\n#{response_body}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def gem_install(file_path, scope: $openc3_scope)
|
49
|
+
response_body = nil
|
50
|
+
begin
|
51
|
+
endpoint = "/openc3-api/gems?scope=#{scope}"
|
52
|
+
uri = URI.parse($api_server.generate_url + endpoint)
|
53
|
+
auth = $api_server.generate_auth
|
54
|
+
|
55
|
+
File.open(file_path, 'rb') do |file|
|
56
|
+
request = Net::HTTP::Post.new(uri)
|
57
|
+
form_data = [["gem", file]]
|
58
|
+
request.set_form(form_data, "multipart/form-data")
|
59
|
+
request['User-Agent'] = JsonDRbObject::USER_AGENT
|
60
|
+
request['Authorization'] = auth.token
|
61
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
62
|
+
http.request(request) do |response|
|
63
|
+
response_body = response.body
|
64
|
+
response.value() # Raises an HTTP error if the response is not 2xx (success)
|
65
|
+
return response_body.remove_quotes
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
rescue => error
|
70
|
+
raise "gem_install failed due to #{error.formatted}\nResponse:\n#{response_body}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def gem_uninstall(gem_name, scope: $openc3_scope)
|
75
|
+
response_body = nil
|
76
|
+
begin
|
77
|
+
endpoint = "/openc3-api/gems/#{gem_name}?scope=#{scope}"
|
78
|
+
uri = URI.parse($api_server.generate_url + endpoint)
|
79
|
+
auth = $api_server.generate_auth
|
80
|
+
request = Net::HTTP::Delete.new(uri)
|
81
|
+
request['User-Agent'] = JsonDRbObject::USER_AGENT
|
82
|
+
request['Authorization'] = auth.token
|
83
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
84
|
+
http.request(request) do |response|
|
85
|
+
response_body = response.body
|
86
|
+
response.value() # Raises an HTTP error if the response is not 2xx (success)
|
87
|
+
return true
|
88
|
+
end
|
89
|
+
end
|
90
|
+
rescue => error
|
91
|
+
raise "gem_uninstall failed due to #{error.formatted}\nResponse:\n#{response_body}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def gem_status(process_name, scope: $openc3_scope)
|
96
|
+
return plugin_status(process_name, scope: scope)
|
97
|
+
end
|
98
|
+
|
99
|
+
def gem_download(gem_name, local_file_path, scope: $openc3_scope)
|
100
|
+
response_body = nil
|
101
|
+
begin
|
102
|
+
endpoint = "/openc3-api/gems/#{gem_name}/download?scope=#{scope}"
|
103
|
+
uri = URI.parse($api_server.generate_url + endpoint)
|
104
|
+
auth = $api_server.generate_auth
|
105
|
+
request = Net::HTTP::Post.new(uri)
|
106
|
+
request['User-Agent'] = JsonDRbObject::USER_AGENT
|
107
|
+
request['Authorization'] = auth.token
|
108
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
109
|
+
http.request(request) do |response|
|
110
|
+
response_body = response.body
|
111
|
+
response.value() # Raises an HTTP error if the response is not 2xx (success)
|
112
|
+
parsed = JSON.parse(response.body, allow_nan: true, create_additions: true)
|
113
|
+
File.open(local_file_path, 'wb') do |file|
|
114
|
+
file.write(Base64.decode64(parsed['contents']))
|
115
|
+
end
|
116
|
+
return local_file_path
|
117
|
+
end
|
118
|
+
end
|
119
|
+
rescue => error
|
120
|
+
raise "gem_uninstall failed due to #{error.formatted}\nResponse:\n#{response_body}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2023 OpenC3, Inc.
|
4
|
+
# All Rights Reserved.
|
5
|
+
#
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
7
|
+
# under the terms of the GNU Affero General Public License
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# This file may also be used under the terms of a commercial license
|
17
|
+
# if purchased from OpenC3, Inc.
|
18
|
+
|
19
|
+
module OpenC3
|
20
|
+
module Script
|
21
|
+
private
|
22
|
+
|
23
|
+
def plugin_list(scope: $openc3_scope)
|
24
|
+
response_body = nil
|
25
|
+
begin
|
26
|
+
endpoint = "/openc3-api/plugins?scope=#{scope}"
|
27
|
+
uri = URI.parse($api_server.generate_url + endpoint)
|
28
|
+
auth = $api_server.generate_auth
|
29
|
+
|
30
|
+
request = Net::HTTP::Get.new(uri)
|
31
|
+
request['User-Agent'] = JsonDRbObject::USER_AGENT
|
32
|
+
request['Content-Type'] = 'application/json'
|
33
|
+
request['Authorization'] = auth.token
|
34
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
35
|
+
http.request(request) do |response|
|
36
|
+
response_body = response.body
|
37
|
+
response.value() # Raises an HTTP error if the response is not 2xx (success)
|
38
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
rescue => error
|
42
|
+
raise "get_plugin_list failed due to #{error.formatted}\nResponse:\n#{response_body}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def plugin_get(plugin_name, scope: $openc3_scope)
|
47
|
+
response_body = nil
|
48
|
+
begin
|
49
|
+
endpoint = "/openc3-api/plugins/#{plugin_name}?scope=#{scope}"
|
50
|
+
uri = URI.parse($api_server.generate_url + endpoint)
|
51
|
+
auth = $api_server.generate_auth
|
52
|
+
|
53
|
+
request = Net::HTTP::Get.new(uri)
|
54
|
+
request['User-Agent'] = JsonDRbObject::USER_AGENT
|
55
|
+
request['Content-Type'] = 'application/json'
|
56
|
+
request['Authorization'] = auth.token
|
57
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
58
|
+
http.request(request) do |response|
|
59
|
+
response_body = response.body
|
60
|
+
response.value() # Raises an HTTP error if the response is not 2xx (success)
|
61
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
rescue => error
|
65
|
+
raise "get_plugin failed due to #{error.formatted}\nResponse:\n#{response_body}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def plugin_install_phase1(file_path, update: false, existing_plugin_name: nil, scope: $openc3_scope)
|
70
|
+
response_body = nil
|
71
|
+
begin
|
72
|
+
if update
|
73
|
+
endpoint = "/openc3-api/plugins/#{existing_plugin_name}?scope=#{scope}"
|
74
|
+
else
|
75
|
+
endpoint = "/openc3-api/plugins?scope=#{scope}"
|
76
|
+
end
|
77
|
+
uri = URI.parse($api_server.generate_url + endpoint)
|
78
|
+
auth = $api_server.generate_auth
|
79
|
+
|
80
|
+
File.open(file_path, 'rb') do |file|
|
81
|
+
if update
|
82
|
+
request = Net::HTTP::Put.new(uri)
|
83
|
+
else
|
84
|
+
request = Net::HTTP::Post.new(uri)
|
85
|
+
end
|
86
|
+
form_data = [["plugin", file]]
|
87
|
+
request.set_form(form_data, "multipart/form-data")
|
88
|
+
request['User-Agent'] = JsonDRbObject::USER_AGENT
|
89
|
+
request['Authorization'] = auth.token
|
90
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
91
|
+
http.request(request) do |response|
|
92
|
+
response_body = response.body
|
93
|
+
response.value() # Raises an HTTP error if the response is not 2xx (success)
|
94
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
rescue => error
|
99
|
+
raise "plugin_install_phase1 failed due to #{error.formatted}\nResponse:\n#{response_body}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def plugin_install_phase2(plugin_hash, update: false, scope: $openc3_scope)
|
104
|
+
response_body = nil
|
105
|
+
begin
|
106
|
+
plugin_name = plugin_hash['name']
|
107
|
+
if update
|
108
|
+
endpoint = "/openc3-api/plugins/#{plugin_name}?scope=#{scope}"
|
109
|
+
else
|
110
|
+
endpoint = "/openc3-api/plugins/install/#{plugin_name}?scope=#{scope}"
|
111
|
+
end
|
112
|
+
uri = URI.parse($api_server.generate_url + endpoint)
|
113
|
+
auth = $api_server.generate_auth
|
114
|
+
|
115
|
+
if update
|
116
|
+
request = Net::HTTP::Put.new(uri)
|
117
|
+
else
|
118
|
+
request = Net::HTTP::Post.new(uri)
|
119
|
+
end
|
120
|
+
form_data = [["plugin_hash", JSON.generate(plugin_hash, allow_nan: true)]]
|
121
|
+
request.set_form(form_data)
|
122
|
+
request['User-Agent'] = JsonDRbObject::USER_AGENT
|
123
|
+
request['Content-Type'] = 'application/json'
|
124
|
+
request['Authorization'] = auth.token
|
125
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
126
|
+
http.request(request) do |response|
|
127
|
+
response_body = response.body
|
128
|
+
response.value() # Raises an HTTP error if the response is not 2xx (success)
|
129
|
+
return response_body.remove_quotes
|
130
|
+
end
|
131
|
+
end
|
132
|
+
rescue => error
|
133
|
+
raise "plugin_install_phase2 failed due to #{error.formatted}\nResponse:\n#{response_body}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def plugin_update_phase1(file_path, existing_plugin_name, scope: $openc3_scope)
|
138
|
+
return plugin_install_phase1(file_path, existing_plugin_name: existing_plugin_name, update: true, scope: scope)
|
139
|
+
end
|
140
|
+
|
141
|
+
def plugin_uninstall(plugin_name, scope: $openc3_scope)
|
142
|
+
response_body = nil
|
143
|
+
begin
|
144
|
+
endpoint = "/openc3-api/plugins/#{plugin_name}?scope=#{scope}"
|
145
|
+
uri = URI.parse($api_server.generate_url + endpoint)
|
146
|
+
auth = $api_server.generate_auth
|
147
|
+
request = Net::HTTP::Delete.new(uri)
|
148
|
+
request['User-Agent'] = JsonDRbObject::USER_AGENT
|
149
|
+
request['Authorization'] = auth.token
|
150
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
151
|
+
http.request(request) do |response|
|
152
|
+
response_body = response.body
|
153
|
+
response.value() # Raises an HTTP error if the response is not 2xx (success)
|
154
|
+
return response_body.remove_quotes
|
155
|
+
end
|
156
|
+
end
|
157
|
+
rescue => error
|
158
|
+
raise "plugin_uninstall failed due to #{error.formatted}\nResponse:\n#{response_body}"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def plugin_status(process_name, scope: $openc3_scope)
|
163
|
+
response_body = nil
|
164
|
+
begin
|
165
|
+
endpoint = "/openc3-api/process_status/#{process_name}?scope=#{scope}"
|
166
|
+
uri = URI.parse($api_server.generate_url + endpoint)
|
167
|
+
auth = $api_server.generate_auth
|
168
|
+
|
169
|
+
request = Net::HTTP::Get.new(uri)
|
170
|
+
request['User-Agent'] = JsonDRbObject::USER_AGENT
|
171
|
+
request['Content-Type'] = 'application/json'
|
172
|
+
request['Authorization'] = auth.token
|
173
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
174
|
+
http.request(request) do |response|
|
175
|
+
response_body = response.body
|
176
|
+
response.value() # Raises an HTTP error if the response is not 2xx (success)
|
177
|
+
return JSON.parse(response.body, allow_nan: true, create_additions: true)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
rescue => error
|
181
|
+
raise "plugin_status failed due to #{error.formatted}\nResponse:\n#{response_body}"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2023 OpenC3, Inc.
|
4
|
+
# All Rights Reserved.
|
5
|
+
#
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
7
|
+
# under the terms of the GNU Affero General Public License
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# This file may also be used under the terms of a commercial license
|
17
|
+
# if purchased from OpenC3, Inc.
|
18
|
+
|
19
|
+
module OpenC3
|
20
|
+
module Script
|
21
|
+
private
|
22
|
+
|
23
|
+
def get_screen_list(scope: $openc3_scope)
|
24
|
+
begin
|
25
|
+
endpoint = "/openc3-api/screens"
|
26
|
+
# Pass the name of the ENV variable name where we pull the actual bucket name
|
27
|
+
response = $api_server.request('get', endpoint, scope: scope)
|
28
|
+
if response.nil? || response.code != 200
|
29
|
+
raise "Unexpected response to get_screen_list: #{response.inspect}"
|
30
|
+
end
|
31
|
+
screen_list = {}
|
32
|
+
filenames = JSON.parse(response.body)
|
33
|
+
filenames.each do |filename|
|
34
|
+
# TARGET/screens/filename.txt
|
35
|
+
split_filename = filename.split('/')
|
36
|
+
target_name = split_filename[0]
|
37
|
+
screen_name = File.basename(filename, '.txt').to_s.upcase
|
38
|
+
screen_list[target_name] ||= []
|
39
|
+
screen_list[target_name] << screen_name
|
40
|
+
end
|
41
|
+
return screen_list
|
42
|
+
rescue => error
|
43
|
+
raise "get_screen_list failed due to #{error.formatted}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_screen_definition(target_name, screen_name, scope: $openc3_scope)
|
48
|
+
begin
|
49
|
+
endpoint = "/openc3-api/screen/#{target_name.upcase}/#{screen_name.upcase}"
|
50
|
+
response = $api_server.request('get', endpoint, headers: {
|
51
|
+
Accept: 'text/plain',
|
52
|
+
}, scope: scope)
|
53
|
+
if response.nil? || response.code != 200
|
54
|
+
raise "Screen definition not found: #{target_name} #{screen_name}"
|
55
|
+
end
|
56
|
+
return response.body
|
57
|
+
rescue => error
|
58
|
+
raise "get_screen_definition failed due to #{error.formatted}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_screen(target_name, screen_name, definition, scope: $openc3_scope)
|
63
|
+
begin
|
64
|
+
endpoint = "/openc3-api/screen"
|
65
|
+
data = {
|
66
|
+
"target" => target_name,
|
67
|
+
"screen" => screen_name,
|
68
|
+
"text" => definition
|
69
|
+
}
|
70
|
+
response = $api_server.request('post', endpoint, :data => data, scope: scope)
|
71
|
+
if response.nil? || response.code != 200
|
72
|
+
if response
|
73
|
+
parsed = JSON.parse(response)
|
74
|
+
raise "create_screen error: #{parsed['error']}"
|
75
|
+
else
|
76
|
+
raise "create_screen failed"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
return response.body
|
80
|
+
rescue => error
|
81
|
+
raise "create_screen failed due to #{error.formatted}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def delete_screen(target_name, screen_name, scope: $openc3_scope)
|
86
|
+
begin
|
87
|
+
endpoint = "/openc3-api/screen/#{target_name.upcase}/#{screen_name.upcase}"
|
88
|
+
response = $api_server.request('delete', endpoint, scope: scope)
|
89
|
+
if response.nil? || response.code != 200
|
90
|
+
if response
|
91
|
+
parsed = JSON.parse(response)
|
92
|
+
raise "delete_screen error: #{parsed['error']}"
|
93
|
+
else
|
94
|
+
raise "delete_screen failed"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
return response.body
|
98
|
+
rescue => error
|
99
|
+
raise "delete_screen failed due to #{error.formatted}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def display_screen(target_name, screen_name, x = nil, y = nil, scope: $openc3_scope)
|
104
|
+
# Noop outside of ScriptRunner
|
105
|
+
end
|
106
|
+
|
107
|
+
def clear_screen(target_name, screen_name)
|
108
|
+
# Noop outside of ScriptRunner
|
109
|
+
end
|
110
|
+
|
111
|
+
def clear_all_screens
|
112
|
+
# Noop outside of ScriptRunner
|
113
|
+
end
|
114
|
+
|
115
|
+
def local_screen(screen_name, definition, x = nil, y = nil)
|
116
|
+
# Noop outside of ScriptRunner
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/lib/openc3/script/script.rb
CHANGED
@@ -29,9 +29,12 @@ require 'openc3/script/commands'
|
|
29
29
|
require 'openc3/script/telemetry'
|
30
30
|
require 'openc3/script/limits'
|
31
31
|
require 'openc3/script/exceptions'
|
32
|
+
require 'openc3/script/screen'
|
32
33
|
require 'openc3/script/script_runner'
|
33
34
|
require 'openc3/script/storage'
|
34
35
|
require 'openc3/script/web_socket_api'
|
36
|
+
require 'openc3/script/gems'
|
37
|
+
require 'openc3/script/plugins'
|
35
38
|
require 'openc3/utilities/authentication'
|
36
39
|
|
37
40
|
$api_server = nil
|