openc3 5.0.6

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.
Files changed (307) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +18 -0
  3. data/Guardfile +35 -0
  4. data/LICENSE.txt +727 -0
  5. data/README.md +37 -0
  6. data/Rakefile +131 -0
  7. data/bin/cstol_converter +1178 -0
  8. data/bin/openc3cli +531 -0
  9. data/bin/rubysloc +139 -0
  10. data/data/config/_array_params.yaml +23 -0
  11. data/data/config/_id_items.yaml +24 -0
  12. data/data/config/_id_params.yaml +58 -0
  13. data/data/config/_interfaces.yaml +214 -0
  14. data/data/config/_interfaces.yaml.err +1017 -0
  15. data/data/config/_items.yaml +20 -0
  16. data/data/config/_params.yaml +60 -0
  17. data/data/config/cmd_tlm_server.yaml +136 -0
  18. data/data/config/command.yaml +44 -0
  19. data/data/config/command_modifiers.yaml +160 -0
  20. data/data/config/command_telemetry.yaml +3 -0
  21. data/data/config/interface_modifiers.yaml +104 -0
  22. data/data/config/item_modifiers.yaml +221 -0
  23. data/data/config/microservice.yaml +78 -0
  24. data/data/config/param_item_modifiers.yaml +52 -0
  25. data/data/config/parameter_modifiers.yaml +200 -0
  26. data/data/config/plugins.yaml +80 -0
  27. data/data/config/protocols.yaml +290 -0
  28. data/data/config/screen.yaml +147 -0
  29. data/data/config/table_manager.yaml +89 -0
  30. data/data/config/table_parameter_modifiers.yaml +9 -0
  31. data/data/config/target.yaml +142 -0
  32. data/data/config/target_config.yaml +94 -0
  33. data/data/config/telemetry.yaml +87 -0
  34. data/data/config/telemetry_modifiers.yaml +159 -0
  35. data/data/config/tool.yaml +63 -0
  36. data/data/config/unknown.yaml +3 -0
  37. data/data/config/widgets.yaml +1505 -0
  38. data/ext/mkrf_conf.rb +49 -0
  39. data/ext/openc3/ext/array/array.c +122 -0
  40. data/ext/openc3/ext/array/extconf.rb +13 -0
  41. data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
  42. data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
  43. data/ext/openc3/ext/config_parser/config_parser.c +280 -0
  44. data/ext/openc3/ext/config_parser/extconf.rb +13 -0
  45. data/ext/openc3/ext/crc/crc.c +351 -0
  46. data/ext/openc3/ext/crc/extconf.rb +13 -0
  47. data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
  48. data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
  49. data/ext/openc3/ext/packet/extconf.rb +13 -0
  50. data/ext/openc3/ext/packet/packet.c +318 -0
  51. data/ext/openc3/ext/platform/extconf.rb +13 -0
  52. data/ext/openc3/ext/platform/platform.c +134 -0
  53. data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
  54. data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
  55. data/ext/openc3/ext/string/extconf.rb +13 -0
  56. data/ext/openc3/ext/string/string.c +63 -0
  57. data/ext/openc3/ext/structure/structure.c +1719 -0
  58. data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
  59. data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
  60. data/ext/openc3/ext/telemetry/extconf.rb +13 -0
  61. data/ext/openc3/ext/telemetry/telemetry.c +336 -0
  62. data/lib/cosmos.rb +20 -0
  63. data/lib/cosmosc2.rb +20 -0
  64. data/lib/openc3/api/api.rb +39 -0
  65. data/lib/openc3/api/authorized_api.rb +30 -0
  66. data/lib/openc3/api/cmd_api.rb +451 -0
  67. data/lib/openc3/api/config_api.rb +58 -0
  68. data/lib/openc3/api/interface_api.rb +117 -0
  69. data/lib/openc3/api/limits_api.rb +375 -0
  70. data/lib/openc3/api/router_api.rb +117 -0
  71. data/lib/openc3/api/settings_api.rb +70 -0
  72. data/lib/openc3/api/target_api.rb +78 -0
  73. data/lib/openc3/api/tlm_api.rb +455 -0
  74. data/lib/openc3/bridge/bridge.rb +54 -0
  75. data/lib/openc3/bridge/bridge_config.rb +167 -0
  76. data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
  77. data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
  78. data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
  79. data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
  80. data/lib/openc3/config/config_parser.rb +549 -0
  81. data/lib/openc3/config/meta_config_parser.rb +74 -0
  82. data/lib/openc3/conversions/conversion.rb +70 -0
  83. data/lib/openc3/conversions/generic_conversion.rb +83 -0
  84. data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
  85. data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
  86. data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
  87. data/lib/openc3/conversions/processor_conversion.rb +70 -0
  88. data/lib/openc3/conversions/received_count_conversion.rb +38 -0
  89. data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
  90. data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
  91. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
  92. data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
  93. data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
  94. data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
  95. data/lib/openc3/conversions.rb +34 -0
  96. data/lib/openc3/core_ext/array.rb +416 -0
  97. data/lib/openc3/core_ext/binding.rb +29 -0
  98. data/lib/openc3/core_ext/class.rb +72 -0
  99. data/lib/openc3/core_ext/exception.rb +61 -0
  100. data/lib/openc3/core_ext/file.rb +83 -0
  101. data/lib/openc3/core_ext/hash.rb +37 -0
  102. data/lib/openc3/core_ext/io.rb +134 -0
  103. data/lib/openc3/core_ext/kernel.rb +42 -0
  104. data/lib/openc3/core_ext/math.rb +128 -0
  105. data/lib/openc3/core_ext/matrix.rb +156 -0
  106. data/lib/openc3/core_ext/objectspace.rb +36 -0
  107. data/lib/openc3/core_ext/openc3_io.rb +57 -0
  108. data/lib/openc3/core_ext/range.rb +27 -0
  109. data/lib/openc3/core_ext/socket.rb +38 -0
  110. data/lib/openc3/core_ext/string.rb +389 -0
  111. data/lib/openc3/core_ext/stringio.rb +33 -0
  112. data/lib/openc3/core_ext/time.rb +508 -0
  113. data/lib/openc3/core_ext.rb +36 -0
  114. data/lib/openc3/interfaces/interface.rb +498 -0
  115. data/lib/openc3/interfaces/linc_interface.rb +475 -0
  116. data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
  117. data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
  118. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
  119. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
  120. data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
  121. data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
  122. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
  123. data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
  124. data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
  125. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
  126. data/lib/openc3/interfaces/serial_interface.rb +94 -0
  127. data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
  128. data/lib/openc3/interfaces/stream_interface.rb +81 -0
  129. data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
  130. data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
  131. data/lib/openc3/interfaces/udp_interface.rb +169 -0
  132. data/lib/openc3/interfaces.rb +44 -0
  133. data/lib/openc3/io/buffered_file.rb +109 -0
  134. data/lib/openc3/io/io_multiplexer.rb +80 -0
  135. data/lib/openc3/io/json_api_object.rb +208 -0
  136. data/lib/openc3/io/json_drb.rb +335 -0
  137. data/lib/openc3/io/json_drb_object.rb +114 -0
  138. data/lib/openc3/io/json_drb_rack.rb +84 -0
  139. data/lib/openc3/io/json_rpc.rb +420 -0
  140. data/lib/openc3/io/openc3_snmp.rb +58 -0
  141. data/lib/openc3/io/posix_serial_driver.rb +156 -0
  142. data/lib/openc3/io/raw_logger.rb +167 -0
  143. data/lib/openc3/io/raw_logger_pair.rb +77 -0
  144. data/lib/openc3/io/serial_driver.rb +105 -0
  145. data/lib/openc3/io/stderr.rb +43 -0
  146. data/lib/openc3/io/stdout.rb +43 -0
  147. data/lib/openc3/io/udp_sockets.rb +194 -0
  148. data/lib/openc3/io/win32_serial_driver.rb +196 -0
  149. data/lib/openc3/logs/log_writer.rb +302 -0
  150. data/lib/openc3/logs/packet_log_constants.rb +62 -0
  151. data/lib/openc3/logs/packet_log_reader.rb +345 -0
  152. data/lib/openc3/logs/packet_log_writer.rb +299 -0
  153. data/lib/openc3/logs/text_log_writer.rb +68 -0
  154. data/lib/openc3/logs.rb +25 -0
  155. data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
  156. data/lib/openc3/microservices/decom_microservice.rb +136 -0
  157. data/lib/openc3/microservices/interface_microservice.rb +532 -0
  158. data/lib/openc3/microservices/log_microservice.rb +108 -0
  159. data/lib/openc3/microservices/microservice.rb +204 -0
  160. data/lib/openc3/microservices/plugin_microservice.rb +43 -0
  161. data/lib/openc3/microservices/reaction_microservice.rb +541 -0
  162. data/lib/openc3/microservices/reducer_microservice.rb +313 -0
  163. data/lib/openc3/microservices/router_microservice.rb +44 -0
  164. data/lib/openc3/microservices/text_log_microservice.rb +84 -0
  165. data/lib/openc3/microservices/timeline_microservice.rb +363 -0
  166. data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
  167. data/lib/openc3/models/activity_model.rb +319 -0
  168. data/lib/openc3/models/auth_model.rb +65 -0
  169. data/lib/openc3/models/cvt_model.rb +185 -0
  170. data/lib/openc3/models/environment_model.rb +58 -0
  171. data/lib/openc3/models/gem_model.rb +137 -0
  172. data/lib/openc3/models/info_model.rb +31 -0
  173. data/lib/openc3/models/interface_model.rb +281 -0
  174. data/lib/openc3/models/interface_status_model.rb +117 -0
  175. data/lib/openc3/models/metadata_model.rb +139 -0
  176. data/lib/openc3/models/metric_model.rb +59 -0
  177. data/lib/openc3/models/microservice_model.rb +206 -0
  178. data/lib/openc3/models/microservice_status_model.rb +74 -0
  179. data/lib/openc3/models/model.rb +204 -0
  180. data/lib/openc3/models/note_model.rb +122 -0
  181. data/lib/openc3/models/notification_model.rb +40 -0
  182. data/lib/openc3/models/ping_model.rb +35 -0
  183. data/lib/openc3/models/plugin_model.rb +292 -0
  184. data/lib/openc3/models/process_status_model.rb +76 -0
  185. data/lib/openc3/models/reaction_model.rb +322 -0
  186. data/lib/openc3/models/reducer_model.rb +65 -0
  187. data/lib/openc3/models/router_model.rb +35 -0
  188. data/lib/openc3/models/router_status_model.rb +27 -0
  189. data/lib/openc3/models/scope_model.rb +153 -0
  190. data/lib/openc3/models/settings_model.rb +55 -0
  191. data/lib/openc3/models/sorted_model.rb +167 -0
  192. data/lib/openc3/models/target_model.rb +759 -0
  193. data/lib/openc3/models/timeline_model.rb +154 -0
  194. data/lib/openc3/models/tool_config_model.rb +38 -0
  195. data/lib/openc3/models/tool_model.rb +262 -0
  196. data/lib/openc3/models/trigger_group_model.rb +186 -0
  197. data/lib/openc3/models/trigger_model.rb +330 -0
  198. data/lib/openc3/models/widget_model.rb +138 -0
  199. data/lib/openc3/operators/microservice_operator.rb +128 -0
  200. data/lib/openc3/operators/operator.rb +277 -0
  201. data/lib/openc3/packets/binary_accessor.rb +1207 -0
  202. data/lib/openc3/packets/commands.rb +373 -0
  203. data/lib/openc3/packets/json_packet.rb +134 -0
  204. data/lib/openc3/packets/limits.rb +271 -0
  205. data/lib/openc3/packets/limits_response.rb +53 -0
  206. data/lib/openc3/packets/packet.rb +1168 -0
  207. data/lib/openc3/packets/packet_config.rb +625 -0
  208. data/lib/openc3/packets/packet_item.rb +586 -0
  209. data/lib/openc3/packets/packet_item_limits.rb +162 -0
  210. data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
  211. data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
  212. data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
  213. data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
  214. data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
  215. data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
  216. data/lib/openc3/packets/parsers/state_parser.rb +127 -0
  217. data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
  218. data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
  219. data/lib/openc3/packets/structure.rb +553 -0
  220. data/lib/openc3/packets/structure_item.rb +365 -0
  221. data/lib/openc3/packets/telemetry.rb +487 -0
  222. data/lib/openc3/processors/processor.rb +86 -0
  223. data/lib/openc3/processors/statistics_processor.rb +82 -0
  224. data/lib/openc3/processors/watermark_processor.rb +58 -0
  225. data/lib/openc3/processors.rb +24 -0
  226. data/lib/openc3/script/api_shared.rb +828 -0
  227. data/lib/openc3/script/calendar.rb +89 -0
  228. data/lib/openc3/script/commands.rb +227 -0
  229. data/lib/openc3/script/exceptions.rb +29 -0
  230. data/lib/openc3/script/extract.rb +161 -0
  231. data/lib/openc3/script/limits.rb +60 -0
  232. data/lib/openc3/script/script.rb +299 -0
  233. data/lib/openc3/script/script_runner.rb +238 -0
  234. data/lib/openc3/script/storage.rb +146 -0
  235. data/lib/openc3/script/suite.rb +542 -0
  236. data/lib/openc3/script/suite_results.rb +196 -0
  237. data/lib/openc3/script/suite_runner.rb +217 -0
  238. data/lib/openc3/script.rb +21 -0
  239. data/lib/openc3/streams/serial_stream.rb +167 -0
  240. data/lib/openc3/streams/stream.rb +63 -0
  241. data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
  242. data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
  243. data/lib/openc3/system/system.rb +127 -0
  244. data/lib/openc3/system/system_config.rb +411 -0
  245. data/lib/openc3/system/target.rb +269 -0
  246. data/lib/openc3/system.rb +24 -0
  247. data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
  248. data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
  249. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
  250. data/lib/openc3/tools/table_manager/table.rb +77 -0
  251. data/lib/openc3/tools/table_manager/table_config.rb +273 -0
  252. data/lib/openc3/tools/table_manager/table_item.rb +90 -0
  253. data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
  254. data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
  255. data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
  256. data/lib/openc3/tools/test_runner/test.rb +67 -0
  257. data/lib/openc3/top_level.rb +595 -0
  258. data/lib/openc3/topics/autonomic_topic.rb +52 -0
  259. data/lib/openc3/topics/calendar_topic.rb +44 -0
  260. data/lib/openc3/topics/command_decom_topic.rb +76 -0
  261. data/lib/openc3/topics/command_topic.rb +83 -0
  262. data/lib/openc3/topics/config_topic.rb +68 -0
  263. data/lib/openc3/topics/interface_topic.rb +73 -0
  264. data/lib/openc3/topics/limits_event_topic.rb +109 -0
  265. data/lib/openc3/topics/notifications_topic.rb +28 -0
  266. data/lib/openc3/topics/router_topic.rb +85 -0
  267. data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
  268. data/lib/openc3/topics/telemetry_topic.rb +36 -0
  269. data/lib/openc3/topics/timeline_topic.rb +45 -0
  270. data/lib/openc3/topics/topic.rb +53 -0
  271. data/lib/openc3/utilities/authentication.rb +141 -0
  272. data/lib/openc3/utilities/authorization.rb +51 -0
  273. data/lib/openc3/utilities/crc.rb +278 -0
  274. data/lib/openc3/utilities/csv.rb +153 -0
  275. data/lib/openc3/utilities/logger.rb +187 -0
  276. data/lib/openc3/utilities/message_log.rb +91 -0
  277. data/lib/openc3/utilities/metric.rb +141 -0
  278. data/lib/openc3/utilities/process_manager.rb +139 -0
  279. data/lib/openc3/utilities/quaternion.rb +257 -0
  280. data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
  281. data/lib/openc3/utilities/s3.rb +202 -0
  282. data/lib/openc3/utilities/s3_autoload.rb +9 -0
  283. data/lib/openc3/utilities/s3_file_cache.rb +274 -0
  284. data/lib/openc3/utilities/simulated_target.rb +117 -0
  285. data/lib/openc3/utilities/sleeper.rb +51 -0
  286. data/lib/openc3/utilities/store.rb +23 -0
  287. data/lib/openc3/utilities/store_autoload.rb +237 -0
  288. data/lib/openc3/utilities/zip.rb +21 -0
  289. data/lib/openc3/utilities.rb +35 -0
  290. data/lib/openc3/version.rb +14 -0
  291. data/lib/openc3/win32/excel.rb +132 -0
  292. data/lib/openc3/win32/win32.rb +402 -0
  293. data/lib/openc3/win32/win32_main.rb +333 -0
  294. data/lib/openc3.rb +49 -0
  295. data/tasks/gemfile_stats.rake +113 -0
  296. data/tasks/spec.rake +30 -0
  297. data/templates/plugin-template/README.md +15 -0
  298. data/templates/plugin-template/Rakefile +12 -0
  299. data/templates/plugin-template/plugin.gemspec +23 -0
  300. data/templates/plugin-template/plugin.txt +9 -0
  301. data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
  302. data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
  303. data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
  304. data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
  305. data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
  306. data/templates/plugin-template/targets/TARGET/target.txt +5 -0
  307. metadata +849 -0
@@ -0,0 +1,299 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
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
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ require 'openc3'
21
+ require 'openc3/api/api'
22
+ require 'openc3/io/json_drb_object'
23
+ require 'openc3/script/api_shared'
24
+ require 'openc3/script/calendar'
25
+ require 'openc3/script/commands'
26
+ require 'openc3/script/limits'
27
+ require 'openc3/script/exceptions'
28
+ require 'openc3/script/script_runner'
29
+ require 'openc3/script/storage'
30
+ require 'openc3/utilities/authentication'
31
+
32
+ $api_server = nil
33
+ $disconnect = false
34
+ $openc3_scope = ENV['OPENC3_SCOPE'] || 'DEFAULT'
35
+ $openc3_in_cluster = false
36
+
37
+ module OpenC3
38
+ module Script
39
+ private
40
+
41
+ include ApiShared
42
+
43
+ # All methods are private so they can only be called by themselves and not
44
+ # on another object. This is important for the JsonDrbObject class which we
45
+ # use to communicate with the server. JsonDrbObject implements method_missing
46
+ # to forward calls to the remote service. If these methods were not private,
47
+ # they would be included on the $api_server global and would be
48
+ # called directly instead of being forwarded over the JsonDrb connection to
49
+ # the real server.
50
+
51
+ # For each of the Api methods determine if they haven't previously been defined by
52
+ # one of the script files. If not define them and proxy to the $api_server.
53
+ Api::WHITELIST.each do |method|
54
+ unless private_instance_methods(false).include?(method.intern)
55
+ define_method(method.intern) do |*args, **kwargs, &block|
56
+ kwargs[:scope] = $openc3_scope unless kwargs[:scope]
57
+ $api_server.method_missing(method.intern, *args, **kwargs, &block)
58
+ end
59
+ end
60
+ end
61
+
62
+ # Called when this module is mixed in using "include OpenC3::Script"
63
+ def self.included(base)
64
+ initialize_script()
65
+ end
66
+
67
+ def initialize_script
68
+ shutdown_script()
69
+ $disconnect = false
70
+ $api_server = ServerProxy.new
71
+ if $api_server.generate_url =~ /openc3-cmd-tlm-api/
72
+ $openc3_in_cluster = true
73
+ else
74
+ $openc3_in_cluster = false
75
+ end
76
+ $script_runner_api_server = ScriptServerProxy.new
77
+ end
78
+
79
+ def shutdown_script
80
+ $api_server.shutdown if $api_server
81
+ $api_server = nil
82
+ $script_runner_api_server.shutdown if $script_runner_api_server
83
+ $script_runner_api_server = nil
84
+ end
85
+
86
+ def disconnect_script
87
+ $disconnect = true
88
+ end
89
+
90
+ def play_wav_file(wav_filename)
91
+ # NOOP
92
+ end
93
+
94
+ def status_bar(message)
95
+ # NOOP
96
+ end
97
+
98
+ def ask_string(question, blank_or_default = false, password = false)
99
+ answer = ''
100
+ default = ''
101
+ if blank_or_default != true && blank_or_default != false
102
+ question << " (default = #{blank_or_default})"
103
+ allow_blank = true
104
+ else
105
+ allow_blank = blank_or_default
106
+ end
107
+ while answer.empty?
108
+ print question + " "
109
+ answer = gets
110
+ answer.chomp!
111
+ break if allow_blank
112
+ end
113
+ answer = default if answer.empty? and !default.empty?
114
+ return answer
115
+ end
116
+
117
+ def ask(question, blank_or_default = false, password = false)
118
+ string = ask_string(question, blank_or_default, password)
119
+ value = string.convert_to_value
120
+ return value
121
+ end
122
+
123
+ def message_box(string, *buttons, **options)
124
+ print "#{string} (#{buttons.join(", ")}): "
125
+ print "Details: #{details}\n" if details
126
+ gets.chomp
127
+ end
128
+
129
+ def vertical_message_box(string, *buttons, **options)
130
+ message_box(string, *buttons, **options)
131
+ end
132
+
133
+ def combo_box(string, *items, **options)
134
+ message_box(string, *items, **options)
135
+ end
136
+
137
+ def _file_dialog(title, message, filter:)
138
+ answer = ''
139
+ path = "./*"
140
+ path += filter if filter
141
+ files = Dir[path]
142
+ files.select! { |f| !File.directory? f }
143
+ while answer.empty?
144
+ print "#{title}\n#{message}\n#{files.join("\n")}\n<Type file name>:"
145
+ answer = gets
146
+ answer.chomp!
147
+ end
148
+ return answer
149
+ end
150
+
151
+ def open_file_dialog(title, message = "Open File", filter:)
152
+ _file_dialog(title, message, filter)
153
+ end
154
+
155
+ def open_files_dialog(title, message = "Open File(s)", filter:)
156
+ _file_dialog(title, message, filter)
157
+ end
158
+
159
+ def prompt_for_hazardous(target_name, cmd_name, hazardous_description)
160
+ loop do
161
+ message = "Warning: Command #{target_name} #{cmd_name} is Hazardous. "
162
+ message << "\n#{hazardous_description}\n" if hazardous_description
163
+ message << "Send? (y): "
164
+ print message
165
+ answer = gets.chomp
166
+ if answer.downcase == 'y'
167
+ return true
168
+ end
169
+ end
170
+ end
171
+
172
+ def prompt(string, text_color: nil, background_color: nil, font_size: nil, font_family: nil, details: nil)
173
+ print "#{string}: "
174
+ print "Details: #{details}\n" if details
175
+ gets.chomp
176
+ end
177
+ end
178
+
179
+ # Provides a proxy to the JsonDRbObject which communicates with the API server
180
+ class ServerProxy
181
+ # pull openc3-cmd-tlm-api url from environment variables
182
+ def generate_url
183
+ schema = ENV['OPENC3_API_SCHEMA'] || 'http'
184
+ hostname = ENV['OPENC3_API_HOSTNAME'] || (ENV['OPENC3_DEVEL'] ? '127.0.0.1' : 'openc3-cmd-tlm-api')
185
+ port = ENV['OPENC3_API_PORT'] || '2901'
186
+ port = port.to_i
187
+ return "#{schema}://#{hostname}:#{port}"
188
+ end
189
+
190
+ # pull openc3-cmd-tlm-api timeout from environment variables
191
+ def generate_timeout
192
+ timeout = ENV['OPENC3_API_TIMEOUT'] || '1.0'
193
+ return timeout.to_f
194
+ end
195
+
196
+ # generate the auth object
197
+ def generate_auth
198
+ if ENV['OPENC3_API_USER'].nil?
199
+ return OpenC3Authentication.new()
200
+ else
201
+ return OpenC3KeycloakAuthentication.new(ENV['OPENC3_KEYCLOAK_URL'])
202
+ end
203
+ end
204
+
205
+ # Create a JsonDRbObject connection to the API server
206
+ def initialize
207
+ @json_drb = JsonDRbObject.new(
208
+ url: generate_url(),
209
+ timeout: generate_timeout(),
210
+ authentication: generate_auth()
211
+ )
212
+ end
213
+
214
+ # Ruby method which captures any method calls on this object. This allows
215
+ # us to proxy the methods to the API server through the JsonDRbObject.
216
+ def method_missing(method_name, *method_params, **kw_params)
217
+ # Must call shutdown and disconnect on the JsonDRbObject itself
218
+ # to avoid it being sent to the API
219
+ kw_params[:scope] = $openc3_scope unless kw_params[:scope]
220
+ case method_name
221
+ when :shutdown
222
+ @json_drb.shutdown
223
+ when :request
224
+ @json_drb.request(*method_params, **kw_params)
225
+ else
226
+ if $disconnect
227
+ result = nil
228
+ # If :disconnect is there delete it and return the value
229
+ # If it is not there, delete returns nil
230
+ disconnect = kw_params.delete(:disconnect)
231
+ # The only commands allowed through in disconnect mode are read-only
232
+ # Thus we allow the get, list, tlm and limits_enabled and subscribe methods
233
+ if method_name =~ /get_\w*|list_\w*|^tlm|limits_enabled|subscribe/
234
+ result = @json_drb.method_missing(method_name, *method_params, **kw_params)
235
+ end
236
+ # If they overrode the return value using the disconnect keyword then return that
237
+ return disconnect ? disconnect : result
238
+ else
239
+ @json_drb.method_missing(method_name, *method_params, **kw_params)
240
+ end
241
+ end
242
+ end
243
+ end
244
+
245
+ # Provides a proxy to the Script Runner Api which communicates with the API server
246
+ class ScriptServerProxy
247
+ # pull openc3-script-runner-api url from environment variables
248
+ def generate_url
249
+ schema = ENV['OPENC3_SCRIPT_API_SCHEMA'] || 'http'
250
+ hostname = ENV['OPENC3_SCRIPT_API_HOSTNAME'] || (ENV['OPENC3_DEVEL'] ? '127.0.0.1' : 'openc3-script-runner-api')
251
+ port = ENV['OPENC3_SCRIPT_API_PORT'] || '2902'
252
+ port = port.to_i
253
+ return "#{schema}://#{hostname}:#{port}"
254
+ end
255
+
256
+ # pull openc3-cmd-tlm-api timeout from environment variables
257
+ def generate_timeout
258
+ timeout = ENV['OPENC3_SCRIPT_API_TIMEOUT'] || '5.0'
259
+ return timeout.to_f
260
+ end
261
+
262
+ # generate the auth object
263
+ def generate_auth
264
+ if ENV['OPENC3_API_USER'].nil?
265
+ return OpenC3Authentication.new()
266
+ else
267
+ return OpenC3KeycloakAuthentication.new(ENV['OPENC3_KEYCLOAK_URL'])
268
+ end
269
+ end
270
+
271
+ # Create a JsonDRbObject connection to the API server
272
+ def initialize
273
+ @json_api = JsonApiObject.new(
274
+ url: generate_url(),
275
+ timeout: generate_timeout(),
276
+ authentication: generate_auth()
277
+ )
278
+ end
279
+
280
+ def shutdown
281
+ @json_api.shutdown
282
+ end
283
+
284
+ def request(*method_params, **kw_params)
285
+ kw_params[:scope] = $openc3_scope unless kw_params[:scope]
286
+ if $disconnect
287
+ result = nil
288
+ # If :disconnect is there delete it and return the value
289
+ # If it is not there, delete returns nil
290
+ disconnect = kw_params.delete(:disconnect)
291
+
292
+ # If they overrode the return value using the disconnect keyword then return that
293
+ return disconnect ? disconnect : result
294
+ else
295
+ @json_api.request(*method_params, **kw_params)
296
+ end
297
+ end
298
+ end
299
+ end
@@ -0,0 +1,238 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 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
+ module OpenC3
17
+ module Script
18
+ private
19
+
20
+ def _script_response_error(response, message, scope: $openc3_scope)
21
+ if response
22
+ raise "#{message} (#{response.code}): #{response.body}"
23
+ else
24
+ raise "#{message}: No Response"
25
+ end
26
+ end
27
+
28
+ def script_list(scope: $openc3_scope)
29
+ endpoint = "/script-api/scripts"
30
+ response = $script_runner_api_server.request('get', endpoint, scope: scope)
31
+ if response.nil? || response.code != 200
32
+ _script_response_error(response, "Script list request failed", scope: scope)
33
+ else
34
+ return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
35
+ end
36
+ end
37
+
38
+ def script_syntax_check(script, scope: $openc3_scope)
39
+ endpoint = "/script-api/scripts/syntax"
40
+ response = $script_runner_api_server.request('post', endpoint, :data => script, scope: scope)
41
+ if response.nil? || response.code != 200
42
+ _script_response_error(response, "Script syntax check request failed", scope: scope)
43
+ else
44
+ result = JSON.parse(response.body, :allow_nan => true, :create_additions => true)
45
+ if result['title'] == "Syntax Check Successful"
46
+ return true
47
+ else
48
+ raise result.inspect
49
+ end
50
+ end
51
+ end
52
+
53
+ def script_body(filename, scope: $openc3_scope)
54
+ endpoint = "/script-api/scripts/#{filename}"
55
+ response = $script_runner_api_server.request('get', endpoint, scope: scope)
56
+ if response.nil? || response.code != 200
57
+ _script_response_error(response, "Failed to get #{filename}", scope: scope)
58
+ else
59
+ script = response.body
60
+ return script
61
+ end
62
+ end
63
+
64
+ def script_run(filename, disconnect: false, scope: $openc3_scope)
65
+ if disconnect
66
+ endpoint = "/script-api/scripts/#{filename}/run/disconnect"
67
+ else
68
+ endpoint = "/script-api/scripts/#{filename}/run"
69
+ end
70
+ response = $script_runner_api_server.request('post', endpoint, scope: scope)
71
+ if response.nil? || response.code != 200
72
+ _script_response_error(response, "Failed to run #{filename}", scope: scope)
73
+ else
74
+ script_id = Integer(response.body)
75
+ return script_id
76
+ end
77
+ end
78
+
79
+ def script_delete(filename, scope: $openc3_scope)
80
+ endpoint = "/script-api/scripts/#{filename}/delete"
81
+ response = $script_runner_api_server.request('post', endpoint, scope: scope)
82
+ if response.nil? || response.code != 200
83
+ _script_response_error(response, "Failed to delete #{filename}", scope: scope)
84
+ else
85
+ return true
86
+ end
87
+ end
88
+
89
+ def script_lock(filename, scope: $openc3_scope)
90
+ endpoint = "/script-api/scripts/#{filename}/lock"
91
+ response = $script_runner_api_server.request('post', endpoint, scope: scope)
92
+ if response.nil? || response.code != 200
93
+ _script_response_error(response, "Failed to lock #{filename}", scope: scope)
94
+ else
95
+ return true
96
+ end
97
+ end
98
+
99
+ def script_unlock(filename, scope: $openc3_scope)
100
+ endpoint = "/script-api/scripts/#{filename}/unlock"
101
+ response = $script_runner_api_server.request('post', endpoint, scope: scope)
102
+ if response.nil? || response.code != 200
103
+ _script_response_error(response, "Failed to unlock #{filename}", scope: scope)
104
+ else
105
+ return true
106
+ end
107
+ end
108
+
109
+ def script_instrumented(filename, script, scope: $openc3_scope)
110
+ endpoint = "/script-api/scripts/#{filename}/instrumented"
111
+ response = $script_runner_api_server.request('post', endpoint, :data => script, scope: scope)
112
+ if response.nil? || response.code != 200
113
+ _script_response_error(response, "Script instrumented request failed", scope: scope)
114
+ else
115
+ result = JSON.parse(response.body, :allow_nan => true, :create_additions => true)
116
+ if result['title'] == "Instrumented Script"
117
+ parsed = JSON.parse(result['description'], :allow_nan => true, :create_additions => true)
118
+ return parsed.join("\n")
119
+ else
120
+ raise result.inspect
121
+ end
122
+ end
123
+ end
124
+
125
+ def script_create(filename, script, breakpoints = [], scope: $openc3_scope)
126
+ endpoint = "/script-api/scripts/#{filename}"
127
+ response = $script_runner_api_server.request('post', endpoint, :data => {text: script, breakpoints: breakpoints}, scope: scope)
128
+ if response.nil? || response.code != 200
129
+ _script_response_error(response, "Script create request failed", scope: scope)
130
+ else
131
+ return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
132
+ end
133
+ end
134
+
135
+ def script_delete_all_breakpoints(scope: $openc3_scope)
136
+ endpoint = "/script-api/breakpoints/delete/all"
137
+ response = $script_runner_api_server.request('delete', endpoint, scope: scope)
138
+ if response.nil? || response.code != 200
139
+ _script_response_error(response, "Script delete all breakpoints failed", scope: scope)
140
+ else
141
+ return true
142
+ end
143
+ end
144
+
145
+ def running_script_list(scope: $openc3_scope)
146
+ endpoint = "/script-api/running-script"
147
+ response = $script_runner_api_server.request('get', endpoint, scope: scope)
148
+ if response.nil? || response.code != 200
149
+ _script_response_error(response, "Running script list request failed", scope: scope)
150
+ else
151
+ return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
152
+ end
153
+ end
154
+
155
+ def running_script_get(id, scope: $openc3_scope)
156
+ endpoint = "/script-api/running-script/#{id}"
157
+ response = $script_runner_api_server.request('get', endpoint, scope: scope)
158
+ if response.nil? || response.code != 200
159
+ _script_response_error(response, "Running script show request failed", scope: scope)
160
+ else
161
+ return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
162
+ end
163
+ end
164
+
165
+ def _running_script_action(id, action_name, scope: $openc3_scope)
166
+ endpoint = "/script-api/running-script/#{id}/#{action_name}"
167
+ response = $script_runner_api_server.request('post', endpoint, scope: scope)
168
+ if response.nil? || response.code != 200
169
+ _script_response_error(response, "Running script #{action_name} request failed", scope: scope)
170
+ else
171
+ return true
172
+ end
173
+ end
174
+
175
+ def running_script_stop(id, scope: $openc3_scope)
176
+ _running_script_action(id, 'stop', scope: scope)
177
+ end
178
+
179
+ def running_script_pause(id, scope: $openc3_scope)
180
+ _running_script_action(id, 'pause', scope: scope)
181
+ end
182
+
183
+ def running_script_retry(id, scope: $openc3_scope)
184
+ _running_script_action(id, 'retry', scope: scope)
185
+ end
186
+
187
+ def running_script_go(id, scope: $openc3_scope)
188
+ _running_script_action(id, 'go', scope: scope)
189
+ end
190
+
191
+ def running_script_step(id, scope: $openc3_scope)
192
+ _running_script_action(id, 'step', scope: scope)
193
+ end
194
+
195
+ def running_script_delete(id, scope: $openc3_scope)
196
+ _running_script_action(id, 'delete', scope: scope)
197
+ end
198
+
199
+ def running_script_backtrace(id, scope: $openc3_scope)
200
+ _running_script_action(id, 'backtrace', scope: scope)
201
+ end
202
+
203
+ def running_script_debug(id, debug_code, scope: $openc3_scope)
204
+ endpoint = "/script-api/running-script/#{id}/debug"
205
+ response = $script_runner_api_server.request('post', endpoint, data: {'args' => debug_code}, scope: scope)
206
+ if response.nil? || response.code != 200
207
+ _script_response_error(response, "Running script debug request failed", scope: scope)
208
+ else
209
+ return true
210
+ end
211
+ end
212
+
213
+ def running_script_prompt(id, method_name, answer, prompt_id, password: nil, scope: $openc3_scope)
214
+ endpoint = "/script-api/running-script/#{id}/prompt"
215
+ if password
216
+ response = $script_runner_api_server.request('post', endpoint, data: {'method' => method_name, 'answer' => answer, 'prompt_id' => prompt_id, 'password' => password}, scope: scope)
217
+ else
218
+ response = $script_runner_api_server.request('post', endpoint, data: {'method' => method_name, 'answer' => answer, 'prompt_id' => prompt_id}, scope: scope)
219
+ end
220
+ if response.nil? || response.code != 200
221
+ _script_response_error(response, "Running script prompt request failed", scope: scope)
222
+ else
223
+ return true
224
+ end
225
+ end
226
+
227
+ def completed_script_list(scope: $openc3_scope)
228
+ endpoint = "/script-api/completed-scripts"
229
+ response = $script_runner_api_server.request('get', endpoint, scope: scope)
230
+ if response.nil? || response.code != 200
231
+ _script_response_error(response, "Completed script list request failed", scope: scope)
232
+ else
233
+ return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
234
+ end
235
+ end
236
+
237
+ end
238
+ end
@@ -0,0 +1,146 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
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
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ require 'net/http'
21
+
22
+ module OpenC3
23
+ module Script
24
+ private
25
+
26
+ # Delete a file on a target
27
+ #
28
+ # @param [String] Path to a file in a target directory
29
+ def delete_target_file(path, scope: $openc3_scope)
30
+ begin
31
+ # Only delete from the targets_modified
32
+ delete_path = "#{scope}/targets_modified/#{path}"
33
+ endpoint = "/openc3-api/storage/delete/#{delete_path}"
34
+ OpenC3::Logger.info "Deleting #{delete_path}"
35
+ response = $api_server.request('delete', endpoint, query: {bucket: 'config'}, scope: scope)
36
+ if response.nil? || response.code != 200
37
+ raise "Failed to delete #{delete_path}. Note: #{scope}/targets is read-only."
38
+ end
39
+ rescue => error
40
+ raise "Failed deleting #{path} due to #{error.message}"
41
+ end
42
+ nil
43
+ end
44
+
45
+ # Get a handle to write a target file
46
+ #
47
+ # @param path [String] Path to a file in a target directory
48
+ # @param io_or_string [Io or String] IO object
49
+ def put_target_file(path, io_or_string, scope: $openc3_scope)
50
+ raise "Disallowed path modifier '..' found in #{path}" if path.include?('..')
51
+ upload_path = "#{scope}/targets_modified/#{path}"
52
+ endpoint = "/openc3-api/storage/upload/#{upload_path}"
53
+ OpenC3::Logger.info "Writing #{upload_path}"
54
+ result = _get_presigned_request(endpoint, scope: scope)
55
+
56
+ # Try to put the file
57
+ success = false
58
+ begin
59
+ uri = _get_uri(result['url'])
60
+ Net::HTTP.start(uri.host, uri.port) do |http|
61
+ request = Net::HTTP::Put.new(uri, {'Content-Length' => io_or_string.length.to_s})
62
+ if String === io_or_string
63
+ request.body = io_or_string
64
+ else
65
+ request.body_stream = io_or_string
66
+ end
67
+ result = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
68
+ http.request(request)
69
+ end
70
+ return result
71
+ end
72
+ rescue => error
73
+ raise "Failed to write #{upload_path}"
74
+ end
75
+ nil
76
+ end
77
+
78
+ # Get a handle to access a target file
79
+ #
80
+ # @param path [String] Path to a file in a target directory, e.g. "INST/procedures/test.rb"
81
+ # @param original [Boolean] Whether to get the original or modified file
82
+ # @return [File|nil]
83
+ def get_target_file(path, original: false, scope: $openc3_scope)
84
+ part = "targets"
85
+ part += "_modified" unless original
86
+ # Loop to allow redo when switching from modified to original
87
+ loop do
88
+ begin
89
+ return _get_storage_file("#{part}/#{path}", scope: scope)
90
+ rescue => error
91
+ if part == "targets_modified"
92
+ part = "targets"
93
+ redo
94
+ else
95
+ raise error
96
+ end
97
+ end
98
+ break
99
+ end
100
+ end
101
+
102
+ # These are helper methods ... should not be used directly
103
+
104
+ def _get_storage_file(path, scope: $openc3_scope)
105
+ # Create Tempfile to store data
106
+ file = Tempfile.new('target', binmode: true)
107
+
108
+ endpoint = "/openc3-api/storage/download/#{scope}/#{path}"
109
+ OpenC3::Logger.info "Reading #{scope}/#{path}"
110
+ result = _get_presigned_request(endpoint, scope: scope)
111
+
112
+ # Try to get the file
113
+ uri = _get_uri(result['url'])
114
+ Net::HTTP.start(uri.host, uri.port) do |http|
115
+ request = Net::HTTP::Get.new uri
116
+ http.request request do |response|
117
+ response.read_body do |chunk|
118
+ file.write chunk
119
+ end
120
+ end
121
+ file.rewind
122
+ end
123
+ return file
124
+ end
125
+
126
+ def _get_uri(url)
127
+ if $openc3_in_cluster
128
+ uri = URI.parse("http://openc3-minio:9000" + url)
129
+ else
130
+ uri = URI.parse($api_server.generate_url + url)
131
+ end
132
+ end
133
+
134
+ def _get_presigned_request(endpoint, scope: $openc3_scope)
135
+ if $openc3_in_cluster
136
+ response = $api_server.request('get', endpoint, query: { bucket: 'config', internal: true }, scope: scope)
137
+ else
138
+ response = $api_server.request('get', endpoint, query: { bucket: 'config' }, scope: scope)
139
+ end
140
+ if response.nil? || response.code != 201
141
+ raise "Failed to get presigned URL for #{endpoint}"
142
+ end
143
+ JSON.parse(response.body, :allow_nan => true, :create_additions => true)
144
+ end
145
+ end
146
+ end