openc3 7.3.0 → 7.4.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.
Files changed (499) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Guardfile +0 -0
  4. data/LICENSE.md +0 -0
  5. data/README.md +0 -0
  6. data/Rakefile +0 -0
  7. data/bin/openc3cli +138 -0
  8. data/bin/pipuninstall +0 -0
  9. data/bin/uvinstall +10 -3
  10. data/data/config/_array_params.yaml +0 -0
  11. data/data/config/_canvas_values.yaml +0 -0
  12. data/data/config/_graph_params.yaml +0 -0
  13. data/data/config/_id_items.yaml +0 -0
  14. data/data/config/_id_params.yaml +0 -0
  15. data/data/config/_interfaces.yaml +0 -0
  16. data/data/config/_items.yaml +0 -0
  17. data/data/config/_params.yaml +0 -0
  18. data/data/config/command.yaml +0 -0
  19. data/data/config/command_modifiers.yaml +2 -0
  20. data/data/config/command_telemetry.yaml +0 -0
  21. data/data/config/conversions.yaml +0 -0
  22. data/data/config/graph_settings.yaml +0 -0
  23. data/data/config/interface_modifiers.yaml +103 -1
  24. data/data/config/item_modifiers.yaml +0 -0
  25. data/data/config/microservice.yaml +5 -2
  26. data/data/config/param_item_modifiers.yaml +0 -0
  27. data/data/config/parameter_modifiers.yaml +0 -0
  28. data/data/config/plugins.yaml +0 -0
  29. data/data/config/processors.yaml +0 -0
  30. data/data/config/protocols.yaml +0 -0
  31. data/data/config/screen.yaml +0 -0
  32. data/data/config/settings.yaml +0 -0
  33. data/data/config/table_manager.yaml +0 -0
  34. data/data/config/table_parameter_modifiers.yaml +0 -0
  35. data/data/config/target.yaml +0 -0
  36. data/data/config/target_config.yaml +0 -0
  37. data/data/config/telemetry.yaml +0 -0
  38. data/data/config/telemetry_modifiers.yaml +2 -0
  39. data/data/config/tool.yaml +0 -0
  40. data/data/config/unknown.yaml +0 -0
  41. data/data/config/widgets.yaml +6 -0
  42. data/data/xtce_schemas/SpaceSystem_20180204.xsd +0 -0
  43. data/data/xtce_schemas/xml.xsd +0 -0
  44. data/ext/openc3/ext/array/array.c +0 -0
  45. data/ext/openc3/ext/array/extconf.rb +0 -0
  46. data/ext/openc3/ext/buffered_file/buffered_file.c +0 -0
  47. data/ext/openc3/ext/buffered_file/extconf.rb +0 -0
  48. data/ext/openc3/ext/burst_protocol/burst_protocol.c +6 -0
  49. data/ext/openc3/ext/burst_protocol/extconf.rb +0 -0
  50. data/ext/openc3/ext/config_parser/config_parser.c +0 -0
  51. data/ext/openc3/ext/config_parser/extconf.rb +0 -0
  52. data/ext/openc3/ext/crc/crc.c +0 -0
  53. data/ext/openc3/ext/crc/extconf.rb +0 -0
  54. data/ext/openc3/ext/openc3_io/extconf.rb +0 -0
  55. data/ext/openc3/ext/openc3_io/openc3_io.c +0 -0
  56. data/ext/openc3/ext/packet/extconf.rb +0 -0
  57. data/ext/openc3/ext/packet/packet.c +0 -0
  58. data/ext/openc3/ext/platform/extconf.rb +0 -0
  59. data/ext/openc3/ext/platform/platform.c +4 -1
  60. data/ext/openc3/ext/polynomial_conversion/extconf.rb +0 -0
  61. data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +0 -0
  62. data/ext/openc3/ext/string/extconf.rb +0 -0
  63. data/ext/openc3/ext/string/string.c +0 -0
  64. data/ext/openc3/ext/structure/structure.c +49 -17
  65. data/ext/openc3/ext/tabbed_plots_config/extconf.rb +0 -0
  66. data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +0 -0
  67. data/ext/openc3/ext/telemetry/extconf.rb +0 -0
  68. data/ext/openc3/ext/telemetry/telemetry.c +0 -0
  69. data/lib/cosmos.rb +0 -0
  70. data/lib/cosmosc2.rb +0 -0
  71. data/lib/openc3/accessors/accessor.rb +0 -0
  72. data/lib/openc3/accessors/binary_accessor.rb +63 -9
  73. data/lib/openc3/accessors/cbor_accessor.rb +0 -0
  74. data/lib/openc3/accessors/form_accessor.rb +0 -0
  75. data/lib/openc3/accessors/html_accessor.rb +0 -0
  76. data/lib/openc3/accessors/http_accessor.rb +0 -0
  77. data/lib/openc3/accessors/json_accessor.rb +0 -0
  78. data/lib/openc3/accessors/template_accessor.rb +0 -0
  79. data/lib/openc3/accessors/xml_accessor.rb +0 -0
  80. data/lib/openc3/accessors.rb +0 -0
  81. data/lib/openc3/api/README.md +0 -0
  82. data/lib/openc3/api/api.rb +0 -0
  83. data/lib/openc3/api/authorized_api.rb +0 -0
  84. data/lib/openc3/api/calendar_api.rb +0 -0
  85. data/lib/openc3/api/cmd_api.rb +1 -1
  86. data/lib/openc3/api/config_api.rb +0 -0
  87. data/lib/openc3/api/interface_api.rb +0 -0
  88. data/lib/openc3/api/limits_api.rb +0 -0
  89. data/lib/openc3/api/metrics_api.rb +1 -1
  90. data/lib/openc3/api/offline_access_api.rb +1 -1
  91. data/lib/openc3/api/router_api.rb +0 -0
  92. data/lib/openc3/api/settings_api.rb +22 -18
  93. data/lib/openc3/api/stash_api.rb +1 -1
  94. data/lib/openc3/api/target_api.rb +0 -0
  95. data/lib/openc3/api/tlm_api.rb +4 -3
  96. data/lib/openc3/bridge/bridge.rb +0 -0
  97. data/lib/openc3/bridge/bridge_config.rb +0 -0
  98. data/lib/openc3/bridge/bridge_interface_thread.rb +0 -0
  99. data/lib/openc3/bridge/bridge_router_thread.rb +0 -0
  100. data/lib/openc3/ccsds/ccsds_packet.rb +0 -0
  101. data/lib/openc3/ccsds/ccsds_parser.rb +0 -0
  102. data/lib/openc3/config/config_parser.rb +78 -17
  103. data/lib/openc3/config/meta_config_parser.rb +0 -0
  104. data/lib/openc3/conversions/bit_reverse_conversion.rb +0 -0
  105. data/lib/openc3/conversions/conversion.rb +0 -0
  106. data/lib/openc3/conversions/generic_conversion.rb +0 -0
  107. data/lib/openc3/conversions/ip_read_conversion.rb +0 -0
  108. data/lib/openc3/conversions/ip_write_conversion.rb +0 -0
  109. data/lib/openc3/conversions/object_read_conversion.rb +0 -0
  110. data/lib/openc3/conversions/object_write_conversion.rb +0 -0
  111. data/lib/openc3/conversions/packet_time_formatted_conversion.rb +0 -0
  112. data/lib/openc3/conversions/packet_time_seconds_conversion.rb +0 -0
  113. data/lib/openc3/conversions/polynomial_conversion.rb +0 -0
  114. data/lib/openc3/conversions/processor_conversion.rb +0 -0
  115. data/lib/openc3/conversions/received_count_conversion.rb +0 -0
  116. data/lib/openc3/conversions/received_time_formatted_conversion.rb +0 -0
  117. data/lib/openc3/conversions/received_time_seconds_conversion.rb +0 -0
  118. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +0 -0
  119. data/lib/openc3/conversions/unix_time_conversion.rb +0 -0
  120. data/lib/openc3/conversions/unix_time_formatted_conversion.rb +0 -0
  121. data/lib/openc3/conversions/unix_time_seconds_conversion.rb +0 -0
  122. data/lib/openc3/conversions.rb +0 -0
  123. data/lib/openc3/core_ext/array.rb +0 -0
  124. data/lib/openc3/core_ext/binding.rb +0 -0
  125. data/lib/openc3/core_ext/class.rb +0 -0
  126. data/lib/openc3/core_ext/exception.rb +0 -0
  127. data/lib/openc3/core_ext/faraday.rb +0 -0
  128. data/lib/openc3/core_ext/file.rb +0 -0
  129. data/lib/openc3/core_ext/io.rb +0 -0
  130. data/lib/openc3/core_ext/kernel.rb +0 -0
  131. data/lib/openc3/core_ext/math.rb +0 -0
  132. data/lib/openc3/core_ext/matrix.rb +0 -0
  133. data/lib/openc3/core_ext/objectspace.rb +0 -0
  134. data/lib/openc3/core_ext/openc3_io.rb +0 -0
  135. data/lib/openc3/core_ext/range.rb +0 -0
  136. data/lib/openc3/core_ext/socket.rb +0 -0
  137. data/lib/openc3/core_ext/string.rb +0 -0
  138. data/lib/openc3/core_ext/stringio.rb +0 -0
  139. data/lib/openc3/core_ext/tempfile.rb +0 -0
  140. data/lib/openc3/core_ext/time.rb +0 -0
  141. data/lib/openc3/core_ext.rb +0 -0
  142. data/lib/openc3/ext/.keep +0 -0
  143. data/lib/openc3/interfaces/file_interface.rb +0 -0
  144. data/lib/openc3/interfaces/http_client_interface.rb +0 -0
  145. data/lib/openc3/interfaces/http_server_interface.rb +0 -0
  146. data/lib/openc3/interfaces/interface.rb +5 -4
  147. data/lib/openc3/interfaces/mqtt_interface.rb +0 -0
  148. data/lib/openc3/interfaces/mqtt_stream_interface.rb +2 -0
  149. data/lib/openc3/interfaces/protocols/burst_protocol.rb +27 -0
  150. data/lib/openc3/interfaces/protocols/cmd_response_protocol.rb +0 -0
  151. data/lib/openc3/interfaces/protocols/cobs_protocol.rb +0 -0
  152. data/lib/openc3/interfaces/protocols/crc_protocol.rb +0 -0
  153. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +0 -0
  154. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +0 -0
  155. data/lib/openc3/interfaces/protocols/length_protocol.rb +7 -0
  156. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +7 -0
  157. data/lib/openc3/interfaces/protocols/protocol.rb +4 -4
  158. data/lib/openc3/interfaces/protocols/slip_protocol.rb +0 -0
  159. data/lib/openc3/interfaces/protocols/template_protocol.rb +2 -2
  160. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +0 -0
  161. data/lib/openc3/interfaces/serial_interface.rb +2 -0
  162. data/lib/openc3/interfaces/simulated_target_interface.rb +0 -0
  163. data/lib/openc3/interfaces/stream_interface.rb +0 -0
  164. data/lib/openc3/interfaces/tcpip_client_interface.rb +2 -0
  165. data/lib/openc3/interfaces/tcpip_server_interface.rb +0 -0
  166. data/lib/openc3/interfaces/udp_interface.rb +16 -5
  167. data/lib/openc3/interfaces.rb +0 -0
  168. data/lib/openc3/io/buffered_file.rb +0 -0
  169. data/lib/openc3/io/io_multiplexer.rb +0 -0
  170. data/lib/openc3/io/json_api.rb +3 -2
  171. data/lib/openc3/io/json_api_object.rb +0 -0
  172. data/lib/openc3/io/json_drb.rb +20 -4
  173. data/lib/openc3/io/json_drb_object.rb +0 -0
  174. data/lib/openc3/io/json_drb_rack.rb +0 -0
  175. data/lib/openc3/io/json_rpc.rb +0 -0
  176. data/lib/openc3/io/posix_serial_driver.rb +0 -0
  177. data/lib/openc3/io/serial_driver.rb +0 -0
  178. data/lib/openc3/io/stderr.rb +0 -0
  179. data/lib/openc3/io/stdout.rb +0 -0
  180. data/lib/openc3/io/udp_sockets.rb +38 -8
  181. data/lib/openc3/io/win32_serial_driver.rb +1 -0
  182. data/lib/openc3/logs/buffered_packet_log_reader.rb +0 -0
  183. data/lib/openc3/logs/buffered_packet_log_writer.rb +0 -0
  184. data/lib/openc3/logs/log_writer.rb +0 -0
  185. data/lib/openc3/logs/packet_log_constants.rb +0 -0
  186. data/lib/openc3/logs/packet_log_reader.rb +23 -2
  187. data/lib/openc3/logs/packet_log_writer.rb +5 -0
  188. data/lib/openc3/logs/stream_log.rb +1 -1
  189. data/lib/openc3/logs/stream_log_pair.rb +0 -0
  190. data/lib/openc3/logs/text_log_writer.rb +0 -0
  191. data/lib/openc3/logs.rb +0 -0
  192. data/lib/openc3/microservices/cleanup_microservice.rb +0 -0
  193. data/lib/openc3/microservices/decom_common.rb +0 -0
  194. data/lib/openc3/microservices/decom_microservice.rb +0 -0
  195. data/lib/openc3/microservices/interface_decom_common.rb +2 -1
  196. data/lib/openc3/microservices/interface_microservice.rb +72 -25
  197. data/lib/openc3/microservices/log_microservice.rb +0 -0
  198. data/lib/openc3/microservices/microservice.rb +3 -3
  199. data/lib/openc3/microservices/multi_microservice.rb +1 -1
  200. data/lib/openc3/microservices/periodic_microservice.rb +2 -2
  201. data/lib/openc3/microservices/plugin_microservice.rb +0 -0
  202. data/lib/openc3/microservices/queue_microservice.rb +0 -0
  203. data/lib/openc3/microservices/router_microservice.rb +0 -0
  204. data/lib/openc3/microservices/scope_cleanup_microservice.rb +0 -0
  205. data/lib/openc3/microservices/text_log_microservice.rb +0 -0
  206. data/lib/openc3/migrations/20220420190000_log_stuff.rb +0 -0
  207. data/lib/openc3/migrations/20221202214600_add_target_names.rb +0 -0
  208. data/lib/openc3/migrations/20221210174900_convert_to_multi.rb +0 -0
  209. data/lib/openc3/migrations/20230915000002_no_scope_log_messages.rb +0 -0
  210. data/lib/openc3/migrations/20231022000000_tlm_viewer_config.rb +0 -0
  211. data/lib/openc3/migrations/20241208080000_no_critical_cmd.rb +0 -0
  212. data/lib/openc3/migrations/20241208080001_no_trigger_group.rb +0 -0
  213. data/lib/openc3/migrations/20250108060000_news_feed.rb +0 -0
  214. data/lib/openc3/migrations/20250402000000_periodic_only_default.rb +0 -0
  215. data/lib/openc3/migrations/20260203000000_remove_store_id.rb +0 -0
  216. data/lib/openc3/migrations/20260204000000_remove_decom_reducer.rb +0 -0
  217. data/lib/openc3/migrations/20260701000000_updated_at_to_int.rb +0 -0
  218. data/lib/openc3/migrations/20260704000000_default_bridge.rb +38 -0
  219. data/lib/openc3/migrations/20260731000000_system_health_json.rb +11 -0
  220. data/lib/openc3/models/activity_model.rb +0 -0
  221. data/lib/openc3/models/auth_model.rb +35 -7
  222. data/lib/openc3/models/bridge_model.rb +133 -0
  223. data/lib/openc3/models/config_keyword_model.rb +63 -0
  224. data/lib/openc3/models/cvt_model.rb +0 -0
  225. data/lib/openc3/models/db_sharded_model.rb +0 -0
  226. data/lib/openc3/models/environment_model.rb +0 -0
  227. data/lib/openc3/models/gem_model.rb +12 -9
  228. data/lib/openc3/models/host_interface_microservice_model.rb +114 -0
  229. data/lib/openc3/models/info_model.rb +0 -0
  230. data/lib/openc3/models/interface_model.rb +178 -19
  231. data/lib/openc3/models/interface_status_model.rb +0 -0
  232. data/lib/openc3/models/metadata_model.rb +0 -0
  233. data/lib/openc3/models/metric_model.rb +0 -0
  234. data/lib/openc3/models/microservice_model.rb +9 -22
  235. data/lib/openc3/models/microservice_status_model.rb +0 -0
  236. data/lib/openc3/models/migration_model.rb +0 -0
  237. data/lib/openc3/models/model.rb +0 -0
  238. data/lib/openc3/models/news_model.rb +0 -0
  239. data/lib/openc3/models/note_model.rb +0 -0
  240. data/lib/openc3/models/offline_access_model.rb +0 -0
  241. data/lib/openc3/models/ping_model.rb +0 -0
  242. data/lib/openc3/models/plugin_model.rb +9 -2
  243. data/lib/openc3/models/plugin_store_model.rb +0 -0
  244. data/lib/openc3/models/process_status_model.rb +0 -0
  245. data/lib/openc3/models/python_package_model.rb +4 -4
  246. data/lib/openc3/models/queue_model.rb +0 -0
  247. data/lib/openc3/models/reaction_model.rb +0 -0
  248. data/lib/openc3/models/reingest_job_model.rb +0 -0
  249. data/lib/openc3/models/router_model.rb +0 -0
  250. data/lib/openc3/models/router_status_model.rb +0 -0
  251. data/lib/openc3/models/scope_model.rb +51 -26
  252. data/lib/openc3/models/script_engine_model.rb +0 -0
  253. data/lib/openc3/models/script_status_model.rb +0 -0
  254. data/lib/openc3/models/secret_model.rb +0 -0
  255. data/lib/openc3/models/setting_model.rb +546 -3
  256. data/lib/openc3/models/sorted_model.rb +0 -0
  257. data/lib/openc3/models/stash_model.rb +0 -0
  258. data/lib/openc3/models/target_model.rb +30 -25
  259. data/lib/openc3/models/timeline_model.rb +0 -0
  260. data/lib/openc3/models/tool_config_model.rb +0 -0
  261. data/lib/openc3/models/tool_model.rb +1 -0
  262. data/lib/openc3/models/trigger_group_model.rb +0 -0
  263. data/lib/openc3/models/trigger_model.rb +20 -0
  264. data/lib/openc3/models/widget_model.rb +0 -0
  265. data/lib/openc3/operators/microservice_operator.rb +64 -22
  266. data/lib/openc3/operators/operator.rb +4 -4
  267. data/lib/openc3/packets/binary_accessor.rb +0 -0
  268. data/lib/openc3/packets/command_validator.rb +0 -0
  269. data/lib/openc3/packets/commands.rb +0 -0
  270. data/lib/openc3/packets/json_packet.rb +0 -0
  271. data/lib/openc3/packets/limits.rb +0 -0
  272. data/lib/openc3/packets/limits_response.rb +0 -0
  273. data/lib/openc3/packets/packet.rb +4 -0
  274. data/lib/openc3/packets/packet_config.rb +0 -0
  275. data/lib/openc3/packets/packet_item.rb +0 -0
  276. data/lib/openc3/packets/packet_item_limits.rb +0 -0
  277. data/lib/openc3/packets/parsers/format_string_parser.rb +0 -0
  278. data/lib/openc3/packets/parsers/limits_parser.rb +0 -0
  279. data/lib/openc3/packets/parsers/limits_response_parser.rb +0 -0
  280. data/lib/openc3/packets/parsers/packet_item_parser.rb +0 -0
  281. data/lib/openc3/packets/parsers/packet_parser.rb +0 -0
  282. data/lib/openc3/packets/parsers/processor_parser.rb +0 -0
  283. data/lib/openc3/packets/parsers/state_parser.rb +0 -0
  284. data/lib/openc3/packets/parsers/xtce_converter.rb +0 -0
  285. data/lib/openc3/packets/parsers/xtce_parser.rb +0 -0
  286. data/lib/openc3/packets/structure.rb +7 -1
  287. data/lib/openc3/packets/structure_item.rb +0 -0
  288. data/lib/openc3/packets/telemetry.rb +0 -0
  289. data/lib/openc3/processors/processor.rb +2 -0
  290. data/lib/openc3/processors/statistics_processor.rb +0 -0
  291. data/lib/openc3/processors/watermark_processor.rb +0 -0
  292. data/lib/openc3/processors.rb +0 -0
  293. data/lib/openc3/script/api_shared.rb +0 -0
  294. data/lib/openc3/script/autonomic.rb +12 -12
  295. data/lib/openc3/script/calendar.rb +0 -0
  296. data/lib/openc3/script/commands.rb +0 -0
  297. data/lib/openc3/script/critical_cmd.rb +0 -0
  298. data/lib/openc3/script/exceptions.rb +0 -0
  299. data/lib/openc3/script/extract.rb +0 -0
  300. data/lib/openc3/script/limits.rb +0 -0
  301. data/lib/openc3/script/metadata.rb +0 -0
  302. data/lib/openc3/script/packages.rb +0 -0
  303. data/lib/openc3/script/plugins.rb +0 -0
  304. data/lib/openc3/script/queue.rb +0 -0
  305. data/lib/openc3/script/screen.rb +0 -0
  306. data/lib/openc3/script/script.rb +2 -2
  307. data/lib/openc3/script/script_runner.rb +0 -0
  308. data/lib/openc3/script/storage.rb +4 -4
  309. data/lib/openc3/script/suite.rb +0 -0
  310. data/lib/openc3/script/suite_results.rb +0 -0
  311. data/lib/openc3/script/suite_runner.rb +26 -0
  312. data/lib/openc3/script/tables.rb +0 -0
  313. data/lib/openc3/script/telemetry.rb +9 -3
  314. data/lib/openc3/script/web_socket_api.rb +218 -145
  315. data/lib/openc3/script.rb +0 -0
  316. data/lib/openc3/script_engines/script_engine.rb +0 -0
  317. data/lib/openc3/streams/mqtt_stream.rb +0 -0
  318. data/lib/openc3/streams/serial_stream.rb +0 -0
  319. data/lib/openc3/streams/stream.rb +0 -0
  320. data/lib/openc3/streams/tcpip_client_stream.rb +0 -0
  321. data/lib/openc3/streams/tcpip_socket_stream.rb +0 -0
  322. data/lib/openc3/streams/web_socket_client_stream.rb +0 -0
  323. data/lib/openc3/subpacketizers/subpacketizer.rb +0 -0
  324. data/lib/openc3/system/system.rb +0 -0
  325. data/lib/openc3/system/target.rb +0 -0
  326. data/lib/openc3/system.rb +0 -0
  327. data/lib/openc3/tools/cmd_tlm_server/api.rb +0 -0
  328. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +7 -0
  329. data/lib/openc3/tools/table_manager/table.rb +0 -0
  330. data/lib/openc3/tools/table_manager/table_config.rb +0 -0
  331. data/lib/openc3/tools/table_manager/table_item.rb +0 -0
  332. data/lib/openc3/tools/table_manager/table_item_parser.rb +0 -0
  333. data/lib/openc3/tools/table_manager/table_manager_core.rb +0 -0
  334. data/lib/openc3/tools/table_manager/table_parser.rb +0 -0
  335. data/lib/openc3/tools/test_runner/test.rb +0 -0
  336. data/lib/openc3/top_level.rb +1 -1
  337. data/lib/openc3/topics/autonomic_topic.rb +0 -0
  338. data/lib/openc3/topics/calendar_topic.rb +0 -0
  339. data/lib/openc3/topics/command_decom_topic.rb +0 -0
  340. data/lib/openc3/topics/command_topic.rb +0 -0
  341. data/lib/openc3/topics/config_topic.rb +0 -0
  342. data/lib/openc3/topics/decom_interface_topic.rb +2 -1
  343. data/lib/openc3/topics/interface_topic.rb +8 -2
  344. data/lib/openc3/topics/limits_event_topic.rb +0 -0
  345. data/lib/openc3/topics/notebook_topic.rb +0 -0
  346. data/lib/openc3/topics/queue_topic.rb +0 -0
  347. data/lib/openc3/topics/router_topic.rb +6 -1
  348. data/lib/openc3/topics/system_events_topic.rb +0 -0
  349. data/lib/openc3/topics/telemetry_decom_topic.rb +0 -0
  350. data/lib/openc3/topics/telemetry_topic.rb +0 -0
  351. data/lib/openc3/topics/timeline_topic.rb +0 -0
  352. data/lib/openc3/topics/topic.rb +0 -0
  353. data/lib/openc3/utilities/authentication.rb +4 -4
  354. data/lib/openc3/utilities/authorization.rb +0 -0
  355. data/lib/openc3/utilities/aws_bucket.rb +2 -2
  356. data/lib/openc3/utilities/bucket.rb +1 -1
  357. data/lib/openc3/utilities/bucket_file_cache.rb +55 -22
  358. data/lib/openc3/utilities/bucket_require.rb +0 -0
  359. data/lib/openc3/utilities/bucket_utilities.rb +3 -4
  360. data/lib/openc3/utilities/cli_generator.rb +0 -0
  361. data/lib/openc3/utilities/cmd_log.rb +0 -0
  362. data/lib/openc3/utilities/config_overlay.rb +75 -0
  363. data/lib/openc3/utilities/cosmos_rails_formatter.rb +0 -0
  364. data/lib/openc3/utilities/crc.rb +59 -32
  365. data/lib/openc3/utilities/csv.rb +0 -0
  366. data/lib/openc3/utilities/ctrf.rb +0 -0
  367. data/lib/openc3/utilities/env_helper.rb +0 -0
  368. data/lib/openc3/utilities/local_bucket.rb +0 -0
  369. data/lib/openc3/utilities/local_mode.rb +32 -6
  370. data/lib/openc3/utilities/logger.rb +30 -8
  371. data/lib/openc3/utilities/message_log.rb +0 -0
  372. data/lib/openc3/utilities/metric.rb +0 -0
  373. data/lib/openc3/utilities/migration.rb +0 -0
  374. data/lib/openc3/utilities/open_telemetry.rb +0 -0
  375. data/lib/openc3/utilities/process_manager.rb +0 -0
  376. data/lib/openc3/utilities/pypi_url.rb +0 -0
  377. data/lib/openc3/utilities/python_proxy.rb +0 -0
  378. data/lib/openc3/utilities/python_venv.rb +135 -0
  379. data/lib/openc3/utilities/quaternion.rb +0 -0
  380. data/lib/openc3/utilities/questdb_client.rb +0 -0
  381. data/lib/openc3/utilities/redis_secrets.rb +0 -0
  382. data/lib/openc3/utilities/reingest_job.rb +0 -0
  383. data/lib/openc3/utilities/ruby_lex_utils.rb +0 -0
  384. data/lib/openc3/utilities/rubygems_url.rb +39 -0
  385. data/lib/openc3/utilities/running_script.rb +24 -55
  386. data/lib/openc3/utilities/s3_autoload.rb +5 -5
  387. data/lib/openc3/utilities/script.rb +12 -8
  388. data/lib/openc3/utilities/secrets.rb +48 -3
  389. data/lib/openc3/utilities/simulated_target.rb +0 -0
  390. data/lib/openc3/utilities/sleeper.rb +0 -0
  391. data/lib/openc3/utilities/store.rb +0 -0
  392. data/lib/openc3/utilities/store_autoload.rb +2 -2
  393. data/lib/openc3/utilities/store_queued.rb +0 -0
  394. data/lib/openc3/utilities/target_file.rb +18 -1
  395. data/lib/openc3/utilities/thread_manager.rb +0 -0
  396. data/lib/openc3/utilities/throttle.rb +0 -0
  397. data/lib/openc3/utilities/zip.rb +0 -0
  398. data/lib/openc3/utilities.rb +0 -0
  399. data/lib/openc3/version.rb +5 -5
  400. data/lib/openc3/win32/excel.rb +0 -0
  401. data/lib/openc3/win32/win32.rb +0 -0
  402. data/lib/openc3/win32/win32_main.rb +0 -0
  403. data/lib/openc3.rb +2 -2
  404. data/tasks/gemfile_stats.rake +0 -0
  405. data/tasks/spec.rake +0 -0
  406. data/templates/command_validator/command_validator.py +0 -0
  407. data/templates/command_validator/command_validator.rb +0 -0
  408. data/templates/conversion/conversion.py +0 -0
  409. data/templates/conversion/conversion.rb +0 -0
  410. data/templates/limits_response/response.py +0 -0
  411. data/templates/limits_response/response.rb +0 -0
  412. data/templates/microservice/microservices/TEMPLATE/microservice.py +0 -0
  413. data/templates/microservice/microservices/TEMPLATE/microservice.rb +0 -0
  414. data/templates/plugin/.gitignore +0 -0
  415. data/templates/plugin/LICENSE.md +0 -0
  416. data/templates/plugin/README.md +0 -0
  417. data/templates/plugin/Rakefile +0 -0
  418. data/templates/plugin/plugin.gemspec +0 -0
  419. data/templates/plugin/plugin.txt +0 -0
  420. data/templates/processor/processor.py +1 -1
  421. data/templates/processor/processor.rb +0 -0
  422. data/templates/target/targets/TARGET/cmd_tlm/cmd.txt +0 -0
  423. data/templates/target/targets/TARGET/cmd_tlm/tlm.txt +0 -0
  424. data/templates/target/targets/TARGET/lib/target.py +0 -0
  425. data/templates/target/targets/TARGET/lib/target.rb +0 -0
  426. data/templates/target/targets/TARGET/procedures/procedure.py +0 -0
  427. data/templates/target/targets/TARGET/procedures/procedure.rb +0 -0
  428. data/templates/target/targets/TARGET/public/README.txt +0 -0
  429. data/templates/target/targets/TARGET/screens/status.txt +0 -0
  430. data/templates/target/targets/TARGET/target.txt +0 -0
  431. data/templates/tool_angular/.editorconfig +0 -0
  432. data/templates/tool_angular/.gitignore +0 -0
  433. data/templates/tool_angular/.vscode/extensions.json +0 -0
  434. data/templates/tool_angular/.vscode/launch.json +0 -0
  435. data/templates/tool_angular/.vscode/tasks.json +0 -0
  436. data/templates/tool_angular/angular.json +0 -0
  437. data/templates/tool_angular/extra-webpack.config.js +0 -0
  438. data/templates/tool_angular/package.json +2 -2
  439. data/templates/tool_angular/src/app/app-routing.module.ts +0 -0
  440. data/templates/tool_angular/src/app/app.component.html +0 -0
  441. data/templates/tool_angular/src/app/app.component.scss +0 -0
  442. data/templates/tool_angular/src/app/app.component.spec.ts +0 -0
  443. data/templates/tool_angular/src/app/app.component.ts +0 -0
  444. data/templates/tool_angular/src/app/app.module.ts +0 -0
  445. data/templates/tool_angular/src/app/custom-overlay-container.ts +0 -0
  446. data/templates/tool_angular/src/app/empty-route/empty-route.component.ts +0 -0
  447. data/templates/tool_angular/src/app/openc3-api.d.ts +0 -0
  448. data/templates/tool_angular/src/assets/.gitkeep +0 -0
  449. data/templates/tool_angular/src/environments/environment.prod.ts +0 -0
  450. data/templates/tool_angular/src/environments/environment.ts +0 -0
  451. data/templates/tool_angular/src/favicon.ico +0 -0
  452. data/templates/tool_angular/src/index.html +0 -0
  453. data/templates/tool_angular/src/main.single-spa.ts +0 -0
  454. data/templates/tool_angular/src/single-spa/asset-url.ts +0 -0
  455. data/templates/tool_angular/src/single-spa/single-spa-props.ts +0 -0
  456. data/templates/tool_angular/src/styles.scss +0 -0
  457. data/templates/tool_angular/tsconfig.app.json +0 -0
  458. data/templates/tool_angular/tsconfig.json +0 -0
  459. data/templates/tool_angular/tsconfig.spec.json +0 -0
  460. data/templates/tool_react/.eslintrc +0 -0
  461. data/templates/tool_react/.gitignore +0 -0
  462. data/templates/tool_react/.prettierignore +0 -0
  463. data/templates/tool_react/babel.config.json +0 -0
  464. data/templates/tool_react/jest.config.js +0 -0
  465. data/templates/tool_react/package.json +1 -1
  466. data/templates/tool_react/src/openc3-tool_name.js +0 -0
  467. data/templates/tool_react/src/root.component.js +0 -0
  468. data/templates/tool_react/src/root.component.test.js +0 -0
  469. data/templates/tool_react/webpack.config.js +0 -0
  470. data/templates/tool_svelte/.gitignore +0 -0
  471. data/templates/tool_svelte/.prettierignore +0 -0
  472. data/templates/tool_svelte/.prettierrc.js +0 -0
  473. data/templates/tool_svelte/babel.config.js +0 -0
  474. data/templates/tool_svelte/build/smui.css +0 -0
  475. data/templates/tool_svelte/jest.config.js +0 -0
  476. data/templates/tool_svelte/package.json +1 -1
  477. data/templates/tool_svelte/rollup.config.js +0 -0
  478. data/templates/tool_svelte/src/App.svelte +0 -0
  479. data/templates/tool_svelte/src/App.test.js +0 -0
  480. data/templates/tool_svelte/src/theme/_smui-theme.scss +0 -0
  481. data/templates/tool_svelte/src/tool_name.js +0 -0
  482. data/templates/tool_vue/.env.standalone +0 -0
  483. data/templates/tool_vue/.gitignore +0 -0
  484. data/templates/tool_vue/.prettierrc.cjs +0 -0
  485. data/templates/tool_vue/eslint.config.mjs +0 -0
  486. data/templates/tool_vue/jsconfig.json +0 -0
  487. data/templates/tool_vue/package.json +3 -3
  488. data/templates/tool_vue/src/App.vue +0 -0
  489. data/templates/tool_vue/src/main.js +0 -0
  490. data/templates/tool_vue/src/router.js +0 -0
  491. data/templates/tool_vue/src/tools/tool_name/tool_name.vue +0 -0
  492. data/templates/tool_vue/vite.config.js +1 -1
  493. data/templates/widget/.prettierrc.cjs +0 -0
  494. data/templates/widget/LICENSE.md +0 -0
  495. data/templates/widget/Rakefile +0 -0
  496. data/templates/widget/package.json +2 -2
  497. data/templates/widget/src/Widget.vue +0 -0
  498. data/templates/widget/vite.config.js +0 -0
  499. metadata +36 -9
@@ -50,6 +50,7 @@ module OpenC3
50
50
  STRING_TYPE = 'string'.freeze
51
51
  REGEX_TYPE = 'regex'.freeze
52
52
  TRIGGER_TYPE = 'trigger'.freeze
53
+ ITEM_VALUE_TYPES = ['RAW', 'CONVERTED', 'FORMATTED', 'WITH_UNITS'].freeze
53
54
 
54
55
  def self.create_unique_name(group:, scope:)
55
56
  trigger_names = self.names(group: group, scope: scope)
@@ -180,6 +181,24 @@ module OpenC3
180
181
  end
181
182
  end
182
183
 
184
+ # Validate the items hold a legal valueType and reference telemetry items
185
+ # which actually exist. Only called on create and update, never from initialize.
186
+ # Anything which can reject an already persisted trigger must live here rather than
187
+ # in validate_operand, because validate_operand runs on every from_json
188
+ def validate_trigger_items
189
+ {'left' => @left, 'right' => @right}.each do |side, operand|
190
+ next unless operand.is_a?(Hash) and operand['type'] == ITEM_TYPE
191
+ unless ITEM_VALUE_TYPES.include?(operand['valueType'])
192
+ raise TriggerInputError.new "invalid #{side} operand, valueType '#{operand['valueType']}' must be one of #{ITEM_VALUE_TYPES}"
193
+ end
194
+ begin
195
+ TargetModel.packet_item(operand['target'], operand['packet'], operand['item'], scope: @scope)
196
+ rescue StandardError => e
197
+ raise TriggerInputError.new "invalid #{side} trigger: #{e.message}"
198
+ end
199
+ end
200
+ end
201
+
183
202
  # Validate that all root triggers exist, but do not persist dependent changes yet.
184
203
  # Returns the list of root trigger models that need updating.
185
204
  def validate_roots
@@ -207,6 +226,7 @@ module OpenC3
207
226
  unless Store.hget(@primary_key, @name).nil?
208
227
  raise TriggerInputError.new "existing trigger found: '#{@name}'"
209
228
  end
229
+ validate_trigger_items()
210
230
  models = validate_roots()
211
231
  @updated_at = Time.now.to_nsec_from_epoch
212
232
  Store.hset(@primary_key, @name, JSON.generate(as_json, allow_nan: true))
File without changes
@@ -18,6 +18,7 @@
18
18
  require 'openc3'
19
19
  require 'openc3/models/microservice_model'
20
20
  require 'openc3/operators/operator'
21
+ require 'openc3/utilities/python_venv'
21
22
  require 'openc3/utilities/secrets'
22
23
  require 'redis'
23
24
  require 'open3'
@@ -56,28 +57,13 @@ module OpenC3
56
57
  plugin_venv_dir = nil
57
58
  if plugin_name
58
59
  scope = microservice_name.split("__")[0]
59
- sanitized_name = "#{scope}__#{plugin_name}".tr('^a-zA-Z0-9_-', '_')
60
- candidate = "/gems/plugin_venvs/#{sanitized_name}/.venv"
61
- plugin_venv_dir = candidate if File.directory?(candidate)
60
+ plugin_venv_dir = PythonVenv.plugin_venv_path(scope: scope, plugin_name: plugin_name)
62
61
  end
63
62
 
64
63
  if plugin_venv_dir
65
- env['VIRTUAL_ENV'] = plugin_venv_dir
66
- env['PATH'] = "#{plugin_venv_dir}/bin:#{ENV.fetch('PATH', '')}"
67
- env['PYTHONUSERBASE'] = plugin_venv_dir
68
- # Add the plugin venv's site-packages to PYTHONPATH so the base venv's
69
- # Python binary can find plugin-specific packages. We keep the base binary
70
- # because it has openc3 core installed; PYTHONPATH is always respected by
71
- # CPython regardless of venv activation state.
72
- site_packages = Dir.glob("#{plugin_venv_dir}/lib/python*/site-packages").first
73
- existing_pythonpath = ENV.fetch('PYTHONPATH', '')
74
- if site_packages
75
- env['PYTHONPATH'] = existing_pythonpath.empty? ? site_packages : "#{site_packages}:#{existing_pythonpath}"
76
- else
77
- env['PYTHONPATH'] = existing_pythonpath.empty? ? nil : existing_pythonpath
78
- end
64
+ PythonVenv.configure_environment(env, plugin_venv_dir)
79
65
  else
80
- env['PYTHONUSERBASE'] = '/gems/python_packages'
66
+ env['PYTHONUSERBASE'] = PythonVenv::DEFAULT_PYTHONUSERBASE
81
67
  env['PYTHONPATH'] = ENV.fetch('PYTHONPATH', nil)
82
68
  end
83
69
  else
@@ -98,10 +84,7 @@ module OpenC3
98
84
  if type == 'ENV'
99
85
  env[env_name_or_path] = secret_value
100
86
  elsif type == 'FILE'
101
- FileUtils.mkdir_p(File.dirname(env_name_or_path))
102
- File.open(env_name_or_path, 'wb') do |file|
103
- file.write(secret_value)
104
- end
87
+ write_secret_file(microservice_name, secret_name, env_name_or_path, secret_value)
105
88
  end
106
89
  else
107
90
  Logger.error("Microservice #{microservice_name} references unknown secret: #{secret_name}")
@@ -112,6 +95,65 @@ module OpenC3
112
95
  return process_definition, work_dir, env, scope, container
113
96
  end
114
97
 
98
+ # Writes a FILE type secret to disk. The path is first validated lexically
99
+ # (see Secrets.validate_file_path) and then checked against the filesystem to
100
+ # make sure no symlink redirects the write outside of Secrets.secret_file_dir.
101
+ # Both checks happen before any directory is created so that mkdir_p can
102
+ # never create directories outside of the base.
103
+ def write_secret_file(microservice_name, secret_name, env_name_or_path, secret_value)
104
+ begin
105
+ path = Secrets.validate_file_path(env_name_or_path)
106
+ rescue ArgumentError => error
107
+ Logger.error("Microservice #{microservice_name} secret #{secret_name} has an invalid file path: #{error.message}")
108
+ return
109
+ end
110
+
111
+ # validate_file_path is purely lexical, so a symlink under the secret file
112
+ # directory could still redirect the write outside of it. Resolve symlinks
113
+ # here, where the filesystem being written to is the one being checked.
114
+ begin
115
+ real_base = File.realpath(Secrets.secret_file_dir)
116
+ rescue SystemCallError => error
117
+ Logger.error("Microservice #{microservice_name} secret #{secret_name} secret file directory is unusable: #{error.message}")
118
+ return
119
+ end
120
+
121
+ # Check the deepest directory that already exists before creating anything.
122
+ # If an existing component is a symlink out of the base, mkdir_p would
123
+ # otherwise create the remaining directories outside of it.
124
+ dir = File.dirname(path)
125
+ existing = dir
126
+ existing = File.dirname(existing) until File.directory?(existing) or existing == File.dirname(existing)
127
+ begin
128
+ real_existing = File.realpath(existing)
129
+ rescue SystemCallError => error
130
+ Logger.error("Microservice #{microservice_name} secret #{secret_name} file path is unusable: #{error.message}")
131
+ return
132
+ end
133
+ unless Secrets.path_contained?(real_base, real_existing)
134
+ Logger.error("Microservice #{microservice_name} secret #{secret_name} file path contains a symlinked directory which resolves outside of #{real_base}: #{path}")
135
+ return
136
+ end
137
+
138
+ FileUtils.mkdir_p(dir)
139
+ # Re-check after creating the directories in case one was created through a
140
+ # symlink or the tree changed underneath us.
141
+ real_dir = File.realpath(dir)
142
+ unless Secrets.path_contained?(real_base, real_dir)
143
+ Logger.error("Microservice #{microservice_name} secret #{secret_name} file path resolves outside of #{real_base}: #{path}")
144
+ return
145
+ end
146
+ # File.symlink? uses lstat and so does not follow the link, unlike the
147
+ # File.open below which would write through it.
148
+ if File.symlink?(path)
149
+ Logger.error("Microservice #{microservice_name} secret #{secret_name} file path is a symlink which is not allowed: #{path}")
150
+ return
151
+ end
152
+ File.open(path, 'wb') do |file|
153
+ file.write(secret_value)
154
+ end
155
+ end
156
+
115
157
  # Handle the detection of a new microservice model
116
158
  def handle_new_microservice(microservice_name, microservice_config)
117
159
  parent = microservice_config['parent']
@@ -233,18 +233,18 @@ module OpenC3
233
233
  PROCESS_SHUTDOWN_SECONDS = 5.0
234
234
 
235
235
  def initialize
236
- Logger.level = Logger::INFO
236
+ Logger.level = Logger.default_level
237
237
  Logger.microservice_name = 'MicroserviceOperator'
238
238
 
239
239
  OperatorProcess.setup()
240
- @cycle_time = (ENV['OPERATOR_CYCLE_TIME'] and ENV['OPERATOR_CYCLE_TIME'].to_f) || CYCLE_TIME # time in seconds
240
+ @cycle_time = ENV.fetch('OPERATOR_CYCLE_TIME', CYCLE_TIME).to_f # time in seconds
241
241
  # Maximum number of new microservices to start per cycle. This spreads a
242
242
  # large startup burst (e.g. installing a plugin with many targets) across
243
243
  # multiple cycles so the shared services (object store, redis) aren't
244
244
  # stampeded by every microservice connecting at once. 0 = no limit.
245
- @max_start_per_cycle = (ENV['OPENC3_OPERATOR_MAX_START_PER_CYCLE'] || 5).to_i
245
+ @max_start_per_cycle = ENV.fetch('OPENC3_OPERATOR_MAX_START_PER_CYCLE', 5).to_i
246
246
 
247
- @ruby_process_name = ENV['OPENC3_RUBY']
247
+ @ruby_process_name = ENV.fetch('OPENC3_RUBY', nil)
248
248
  if RUBY_ENGINE != 'ruby'
249
249
  @ruby_process_name ||= 'jruby'
250
250
  else
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -637,6 +637,10 @@ module OpenC3
637
637
  else
638
638
  value = super(item, :RAW, buffer)
639
639
  end
640
+ # An item beyond the end of a short buffer reads as nil (ALLOW_SHORT).
641
+ # Conversions, states and format strings can't be applied to a nil value.
642
+ return nil if value.nil? && @short_buffer_allowed && item.data_type != :DERIVED
643
+
640
644
  derived_raw = false
641
645
  if item.data_type == :DERIVED && value_type == :RAW
642
646
  value_type = :CONVERTED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -617,7 +617,13 @@ module OpenC3
617
617
  return 62
618
618
  end
619
619
  else
620
- return (length_value * item.variable_bit_size['length_bits_per_count']) + item.variable_bit_size['length_value_bit_offset']
620
+ total_bit_size = (length_value * item.variable_bit_size['length_bits_per_count']) + item.variable_bit_size['length_value_bit_offset']
621
+ available_bit_size = (@buffer.length * 8) - item.bit_offset
622
+ if total_bit_size < 0 ||
623
+ (!@short_buffer_allowed && (available_bit_size < 0 || total_bit_size > available_bit_size))
624
+ raise ArgumentError, "Variable bit size #{total_bit_size} for item #{item.name} exceeds the #{[available_bit_size, 0].max} bits available in the buffer"
625
+ end
626
+ return total_bit_size
621
627
  end
622
628
  else
623
629
  raise "Length value #{item.variable_bit_size['length_item_name']} for item #{item.name} is nil"
File without changes
File without changes
@@ -15,6 +15,8 @@
15
15
  # This file may also be used under the terms of a commercial license
16
16
  # if purchased from OpenC3, Inc.
17
17
 
18
+ require 'openc3/packets/packet'
19
+
18
20
  module OpenC3
19
21
  class Processor
20
22
  # @return [Symbol] The value type for the processor
File without changes
File without changes
File without changes
File without changes
@@ -67,7 +67,7 @@ module OpenC3
67
67
  if response.nil? || response.status != 200
68
68
  if response
69
69
  parsed = JSON.parse(response.body)
70
- raise "autonomic_group_destroy error: #{parsed['error']}"
70
+ raise "autonomic_group_destroy error: #{parsed['message']}"
71
71
  else
72
72
  raise "autonomic_group_destroy failed"
73
73
  end
@@ -105,7 +105,7 @@ module OpenC3
105
105
  if response.nil? || response.status != 201
106
106
  if response
107
107
  parsed = JSON.parse(response.body)
108
- raise "autonomic_trigger_create error: #{parsed['error']}"
108
+ raise "autonomic_trigger_create error: #{parsed['message']}"
109
109
  else
110
110
  raise "autonomic_trigger_create failed"
111
111
  end
@@ -136,7 +136,7 @@ module OpenC3
136
136
  if response.nil? || response.status != 200
137
137
  if response
138
138
  parsed = JSON.parse(response.body)
139
- raise "autonomic_trigger_enable error: #{parsed['error']}"
139
+ raise "autonomic_trigger_enable error: #{parsed['message']}"
140
140
  else
141
141
  raise "autonomic_trigger_enable failed"
142
142
  end
@@ -154,7 +154,7 @@ module OpenC3
154
154
  if response.nil? || response.status != 200
155
155
  if response
156
156
  parsed = JSON.parse(response.body)
157
- raise "autonomic_trigger_disable error: #{parsed['error']}"
157
+ raise "autonomic_trigger_disable error: #{parsed['message']}"
158
158
  else
159
159
  raise "autonomic_trigger_disable failed"
160
160
  end
@@ -176,7 +176,7 @@ module OpenC3
176
176
  if response.nil? || response.status != 200
177
177
  if response
178
178
  parsed = JSON.parse(response.body)
179
- raise "autonomic_trigger_update error: #{parsed['error']}"
179
+ raise "autonomic_trigger_update error: #{parsed['message']}"
180
180
  else
181
181
  raise "autonomic_trigger_update failed"
182
182
  end
@@ -194,7 +194,7 @@ module OpenC3
194
194
  if response.nil? || response.status != 200
195
195
  if response
196
196
  parsed = JSON.parse(response.body)
197
- raise "autonomic_trigger_destroy error: #{parsed['error']}"
197
+ raise "autonomic_trigger_destroy error: #{parsed['message']}"
198
198
  else
199
199
  raise "autonomic_trigger_destroy failed"
200
200
  end
@@ -232,7 +232,7 @@ module OpenC3
232
232
  if response.nil? || response.status != 201
233
233
  if response
234
234
  parsed = JSON.parse(response.body)
235
- raise "autonomic_reaction_create error: #{parsed['error']}"
235
+ raise "autonomic_reaction_create error: #{parsed['message']}"
236
236
  else
237
237
  raise "autonomic_reaction_create failed"
238
238
  end
@@ -263,7 +263,7 @@ module OpenC3
263
263
  if response.nil? || response.status != 200
264
264
  if response
265
265
  parsed = JSON.parse(response.body)
266
- raise "autonomic_reaction_enable error: #{parsed['error']}"
266
+ raise "autonomic_reaction_enable error: #{parsed['message']}"
267
267
  else
268
268
  raise "autonomic_reaction_enable failed"
269
269
  end
@@ -281,7 +281,7 @@ module OpenC3
281
281
  if response.nil? || response.status != 200
282
282
  if response
283
283
  parsed = JSON.parse(response.body)
284
- raise "autonomic_reaction_disable error: #{parsed['error']}"
284
+ raise "autonomic_reaction_disable error: #{parsed['message']}"
285
285
  else
286
286
  raise "autonomic_reaction_disable failed"
287
287
  end
@@ -299,7 +299,7 @@ module OpenC3
299
299
  if response.nil? || response.status != 200
300
300
  if response
301
301
  parsed = JSON.parse(response.body)
302
- raise "autonomic_reaction_execute error: #{parsed['error']}"
302
+ raise "autonomic_reaction_execute error: #{parsed['message']}"
303
303
  else
304
304
  raise "autonomic_reaction_execute failed"
305
305
  end
@@ -322,7 +322,7 @@ module OpenC3
322
322
  if response.nil? || response.status != 200
323
323
  if response
324
324
  parsed = JSON.parse(response.body)
325
- raise "autonomic_reaction_update error: #{parsed['error']}"
325
+ raise "autonomic_reaction_update error: #{parsed['message']}"
326
326
  else
327
327
  raise "autonomic_reaction_update failed"
328
328
  end
@@ -340,7 +340,7 @@ module OpenC3
340
340
  if response.nil? || response.status != 200
341
341
  if response
342
342
  parsed = JSON.parse(response.body)
343
- raise "autonomic_reaction_destroy error: #{parsed['error']}"
343
+ raise "autonomic_reaction_destroy error: #{parsed['message']}"
344
344
  else
345
345
  raise "autonomic_reaction_destroy failed"
346
346
  end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -241,7 +241,7 @@ module OpenC3
241
241
  # script_run("INST/procedures/collect.rb")
242
242
  #
243
243
  def initialize_offline_access
244
- keycloak_url = ENV['OPENC3_KEYCLOAK_URL']
244
+ keycloak_url = ENV.fetch('OPENC3_KEYCLOAK_URL', nil)
245
245
  if keycloak_url.nil? or keycloak_url.empty?
246
246
  raise "initialize_offline_access only valid in COSMOS Enterprise. OPENC3_KEYCLOAK_URL environment variable must be set."
247
247
  end
@@ -383,4 +383,4 @@ module OpenC3
383
383
  end
384
384
  end
385
385
 
386
- $VERBOSE = saved_verbose
386
+ $VERBOSE = saved_verbose
File without changes
@@ -169,17 +169,17 @@ module OpenC3
169
169
 
170
170
  def _get_uri(url)
171
171
  if $openc3_in_cluster
172
- case ENV['OPENC3_CLOUD']
172
+ case ENV.fetch('OPENC3_CLOUD', nil)
173
173
  when 'local'
174
- bucket_url = ENV["OPENC3_BUCKET_URL"] || "http://openc3-buckets:9000"
174
+ bucket_url = ENV.fetch("OPENC3_BUCKET_URL", "http://openc3-buckets:9000")
175
175
  URI.parse("#{bucket_url}#{url}")
176
176
  when 'aws'
177
- URI.parse("https://s3.#{ENV['AWS_REGION']}.amazonaws.com" + url)
177
+ URI.parse("https://s3.#{ENV.fetch('AWS_REGION')}.amazonaws.com" + url)
178
178
  when 'gcp'
179
179
  URI.parse("https://storage.googleapis.com" + url)
180
180
  # when 'azure'
181
181
  else
182
- raise "Unknown cloud #{ENV['OPENC3_CLOUD']}"
182
+ raise "Unknown cloud #{ENV.fetch('OPENC3_CLOUD', nil)}"
183
183
  end
184
184
  else
185
185
  URI.parse($api_server.generate_url + url)
File without changes
File without changes
@@ -30,6 +30,12 @@ module OpenC3
30
30
  # the values stay consistent in one place.
31
31
  DEFAULT_METHOD = 'start'
32
32
  DEFAULT_OPTIONS = ['continueAfterError'].freeze
33
+ # The only SuiteRunner entry points a client may request
34
+ ALLOWED_METHODS = ['start', 'setup', 'teardown'].freeze
35
+ # Suite and Group are Ruby constant (class) names, optionally namespaced
36
+ CLASS_NAME_REGEX = /\A[A-Z]\w*(::[A-Z]\w*)*\z/
37
+ # Script is a Ruby method name on the Group
38
+ METHOD_NAME_REGEX = /\A[a-z_]\w*[?!]?\z/
33
39
 
34
40
  @@suites = []
35
41
  @@settings = {}
@@ -55,12 +61,32 @@ module OpenC3
55
61
  raise ArgumentError, "Script #{script} requires a Group" if script and not group
56
62
  end
57
63
 
64
+ # Validate that the raw (client supplied) suite_runner values are plain
65
+ # identifiers. These values are interpolated into the Ruby snippet the
66
+ # running script evaluates, so anything other than a bare class / method
67
+ # name must be rejected before it reaches the interpreter.
68
+ def self.validate_identifiers(suite:, group: nil, script: nil, method: nil)
69
+ unless suite.is_a?(String) and CLASS_NAME_REGEX.match?(suite)
70
+ raise ArgumentError, "Invalid Suite name: #{suite.inspect}"
71
+ end
72
+ if group && !(group.is_a?(String) and CLASS_NAME_REGEX.match?(group))
73
+ raise ArgumentError, "Invalid Group name: #{group.inspect}"
74
+ end
75
+ if script && !(script.is_a?(String) and METHOD_NAME_REGEX.match?(script))
76
+ raise ArgumentError, "Invalid Script name: #{script.inspect}"
77
+ end
78
+ if method && !ALLOWED_METHODS.include?(method.to_s)
79
+ raise ArgumentError, "Invalid method: #{method.inspect}"
80
+ end
81
+ end
82
+
58
83
  # Build the canonical, validated suite_runner hash from raw values,
59
84
  # applying defaults. Shared by openc3cli (constructing from CLI flags) and
60
85
  # the running script (normalizing a received hash before dispatch) so the
61
86
  # hash shape, defaults, and validation live in one place.
62
87
  def self.build_options(suite:, group: nil, script: nil, method: nil, options: nil)
63
88
  validate_options(group: group, script: script)
89
+ validate_identifiers(suite: suite, group: group, script: script, method: method)
64
90
  suite_runner = { 'suite' => suite }
65
91
  if group
66
92
  suite_runner['group'] = group
File without changes
@@ -40,9 +40,15 @@ module OpenC3
40
40
  # inject_tlm, set_tlm, override_tlm, and normalize_tlm are implemented here simply to add a puts
41
41
  # these methods modify the telemetry so the user should be notified in the Script Runner log messages
42
42
 
43
- def inject_tlm(target_name, packet_name, item_hash = nil, type: :CONVERTED, stored: false, scope: $openc3_scope, token: $openc3_token)
44
- puts "inject_tlm(\"#{target_name}\", \"#{packet_name}\", #{item_hash}, type: #{type}, stored: #{stored})"
45
- $api_server.method_missing(:inject_tlm, target_name, packet_name, item_hash, type: type, stored: stored, scope: scope, token: token)
43
+ def inject_tlm(target_name, packet_name, item_hash = nil, type: :CONVERTED, stored: false, received_time: nil, scope: $openc3_scope, token: $openc3_token)
44
+ message = "inject_tlm(\"#{target_name}\", \"#{packet_name}\", #{item_hash}, type: #{type}, stored: #{stored}"
45
+ kwargs = { type: type, stored: stored, scope: scope, token: token }
46
+ unless received_time.nil?
47
+ message << ", received_time: #{received_time}"
48
+ kwargs[:received_time] = received_time
49
+ end
50
+ puts "#{message})"
51
+ $api_server.method_missing(:inject_tlm, target_name, packet_name, item_hash, **kwargs)
46
52
  end
47
53
 
48
54
  def set_tlm(*args, type: :ALL, scope: $openc3_scope, token: $openc3_token)