openc3 5.2.0 → 5.4.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of openc3 might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/bin/openc3cli +108 -105
- data/data/config/interface_modifiers.yaml +22 -4
- data/data/config/item_modifiers.yaml +4 -2
- data/data/config/microservice.yaml +18 -0
- data/data/config/table_manager.yaml +2 -2
- data/data/config/tool.yaml +1 -1
- data/ext/openc3/ext/config_parser/config_parser.c +17 -2
- data/lib/openc3/api/api.rb +1 -0
- data/lib/openc3/api/interface_api.rb +12 -0
- data/lib/openc3/api/metrics_api.rb +97 -0
- data/lib/openc3/api/router_api.rb +14 -2
- data/lib/openc3/api/target_api.rb +24 -3
- data/lib/openc3/api/tlm_api.rb +5 -4
- data/lib/openc3/config/config_parser.rb +29 -4
- data/lib/openc3/core_ext/time.rb +6 -1
- data/lib/openc3/interfaces/interface.rb +27 -26
- data/lib/openc3/interfaces/mqtt_interface.rb +240 -0
- data/lib/openc3/interfaces/protocols/override_protocol.rb +2 -61
- data/lib/openc3/interfaces/protocols/protocol.rb +6 -1
- data/lib/openc3/interfaces/simulated_target_interface.rb +1 -3
- data/lib/openc3/interfaces/tcpip_server_interface.rb +0 -11
- data/lib/openc3/interfaces.rb +2 -3
- data/lib/openc3/logs/buffered_packet_log_reader.rb +2 -2
- data/lib/openc3/microservices/cleanup_microservice.rb +17 -1
- data/lib/openc3/microservices/decom_microservice.rb +12 -9
- data/lib/openc3/microservices/interface_microservice.rb +93 -9
- data/lib/openc3/microservices/log_microservice.rb +11 -5
- data/lib/openc3/microservices/microservice.rb +10 -9
- data/lib/openc3/microservices/periodic_microservice.rb +7 -0
- data/lib/openc3/microservices/reaction_microservice.rb +0 -33
- data/lib/openc3/microservices/reducer_microservice.rb +14 -10
- data/lib/openc3/microservices/text_log_microservice.rb +12 -3
- data/lib/openc3/microservices/timeline_microservice.rb +0 -6
- data/lib/openc3/microservices/trigger_group_microservice.rb +0 -20
- data/lib/openc3/models/cvt_model.rb +103 -47
- data/lib/openc3/models/interface_model.rb +23 -0
- data/lib/openc3/models/metric_model.rb +53 -6
- data/lib/openc3/models/microservice_model.rb +15 -1
- data/lib/openc3/models/model.rb +1 -1
- data/lib/openc3/models/plugin_model.rb +6 -1
- data/lib/openc3/models/secret_model.rb +53 -0
- data/lib/openc3/models/target_model.rb +2 -2
- data/lib/openc3/models/tool_model.rb +17 -8
- data/lib/openc3/operators/microservice_operator.rb +25 -0
- data/lib/openc3/operators/operator.rb +5 -1
- data/lib/openc3/packets/packet.rb +21 -7
- data/lib/openc3/packets/packet_item.rb +3 -2
- data/lib/openc3/script/api_shared.rb +18 -2
- data/lib/openc3/script/script.rb +8 -0
- data/lib/openc3/script/script_runner.rb +1 -2
- data/lib/openc3/script/storage.rb +2 -1
- data/lib/openc3/script/suite.rb +15 -11
- data/lib/openc3/system/system.rb +6 -3
- data/lib/openc3/topics/interface_topic.rb +17 -1
- data/lib/openc3/topics/router_topic.rb +17 -1
- data/lib/openc3/utilities/aws_bucket.rb +20 -3
- data/lib/openc3/utilities/bucket.rb +1 -1
- data/lib/openc3/utilities/bucket_file_cache.rb +1 -1
- data/lib/openc3/utilities/bucket_utilities.rb +1 -1
- data/lib/openc3/utilities/local_mode.rb +1 -0
- data/lib/openc3/utilities/metric.rb +77 -101
- data/lib/openc3/utilities/redis_secrets.rb +46 -0
- data/lib/openc3/utilities/s3_autoload.rb +19 -9
- data/lib/openc3/utilities/secrets.rb +63 -0
- data/lib/openc3/utilities/target_file.rb +3 -1
- data/lib/openc3/version.rb +5 -5
- data/templates/plugin-template/LICENSE.txt +7 -0
- data/templates/plugin-template/README.md +4 -3
- data/templates/plugin-template/plugin.gemspec +4 -4
- metadata +22 -3
- data/data/config/_interfaces.yaml.err +0 -1017
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c51fd2722cde933052c2bf5941c3a111a14ae995de868bb6371faf9f32f708e
|
4
|
+
data.tar.gz: 0a1684b608df0335f485e59b29e55e66a1307cb62c7ab76586989a4566096946
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c36db608db41b6f0c1edc8ae6b83293d71eb37984e115d86a9ca9ff1e6aa4f124c3e0d645b1ac01b329d3fd490ef6a3b281ddc2754344bbdc1c78a702258522c
|
7
|
+
data.tar.gz: 754bc2ce9f0fd0066e47731bc5b50279ac5ce166f20752bb5be42d2ce4ab09698212ee82abcfd1ab353aa1e85029f47e5b766b4bfdba60823682c23148754837
|
data/bin/openc3cli
CHANGED
@@ -322,14 +322,14 @@ ensure
|
|
322
322
|
exit(result)
|
323
323
|
end
|
324
324
|
|
325
|
-
def update_plugin(plugin_file_path, plugin_name, variables: nil, plugin_txt_lines: nil, scope:, existing_plugin_name:)
|
325
|
+
def update_plugin(plugin_file_path, plugin_name, variables: nil, plugin_txt_lines: nil, scope:, existing_plugin_name:, force: false)
|
326
326
|
new_gem = File.basename(plugin_file_path)
|
327
327
|
old_gem = existing_plugin_name.split("__")[0]
|
328
328
|
puts "Updating existing plugin: #{existing_plugin_name} with #{File.basename(plugin_file_path)}"
|
329
329
|
plugin_model = OpenC3::PluginModel.get_model(name: existing_plugin_name, scope: scope)
|
330
330
|
begin
|
331
331
|
# Only update if something has changed
|
332
|
-
if (new_gem != old_gem) or (variables and variables != plugin_model.variables) or (plugin_txt_lines and plugin_txt_lines != plugin_model.plugin_txt_lines)
|
332
|
+
if force or (new_gem != old_gem) or (variables and variables != plugin_model.variables) or (plugin_txt_lines and plugin_txt_lines != plugin_model.plugin_txt_lines)
|
333
333
|
puts "Gem version change detected - New: #{new_gem}, Old: #{old_gem}" if new_gem != old_gem
|
334
334
|
if variables and variables != plugin_model.variables
|
335
335
|
pp_variables = ""
|
@@ -360,7 +360,7 @@ end
|
|
360
360
|
# This code is used from the command line and is the same code that gets called if you
|
361
361
|
# edit/upgrade or install a new plugin from the Admin interface
|
362
362
|
#
|
363
|
-
# Usage: cli load gemfile_path [scope] [plugin_hash_file_path]
|
363
|
+
# Usage: cli load gemfile_path [scope] [plugin_hash_file_path] [force]
|
364
364
|
#
|
365
365
|
# With just gemfile_path and/or scope: Will do nothing if any plugin
|
366
366
|
# with the same gem file already exists
|
@@ -370,7 +370,10 @@ end
|
|
370
370
|
# Otherwise, it will be assumed that the plugin is intentionally being installed for a second
|
371
371
|
# time
|
372
372
|
#
|
373
|
-
|
373
|
+
# Pass true as the last argument to force install even if a plugin with
|
374
|
+
# the same version number exists
|
375
|
+
#
|
376
|
+
def load_plugin(plugin_file_path, scope:, plugin_hash_file: nil, force: false)
|
374
377
|
scope ||= 'DEFAULT'
|
375
378
|
# Only create the scope if it doesn't already exist
|
376
379
|
unless OpenC3::ScopeModel.names.include?(scope)
|
@@ -403,7 +406,7 @@ def load_plugin(plugin_file_path, scope:, plugin_hash_file: nil)
|
|
403
406
|
found = true
|
404
407
|
# Upgrade if version changed else do nothing
|
405
408
|
if file_full_name != full_name
|
406
|
-
update_plugin(plugin_file_path, plugin_name, scope: scope, existing_plugin_name: plugin_name)
|
409
|
+
update_plugin(plugin_file_path, plugin_name, scope: scope, existing_plugin_name: plugin_name, force: force)
|
407
410
|
else
|
408
411
|
puts "No version change detected for: #{plugin_name}"
|
409
412
|
end
|
@@ -430,15 +433,16 @@ def load_plugin(plugin_file_path, scope:, plugin_hash_file: nil)
|
|
430
433
|
|
431
434
|
if existing_plugin_hash
|
432
435
|
# Upgrade or Edit
|
433
|
-
update_plugin(plugin_file_path, plugin_hash['name'], variables: plugin_hash['variables'],
|
436
|
+
update_plugin(plugin_file_path, plugin_hash['name'], variables: plugin_hash['variables'], scope: scope,
|
437
|
+
plugin_txt_lines: plugin_hash['plugin_txt_lines'], existing_plugin_name: existing_plugin_hash['name'], force: force)
|
434
438
|
else
|
435
439
|
# New Install
|
436
440
|
puts "Loading new plugin: #{plugin_file_path}\n#{plugin_hash}"
|
437
441
|
plugin_hash = OpenC3::PluginModel.install_phase2(plugin_hash, scope: scope)
|
438
442
|
OpenC3::LocalMode.update_local_plugin(plugin_file_path, plugin_hash, scope: scope)
|
439
443
|
end
|
440
|
-
rescue =>
|
441
|
-
abort("Error installing plugin: #{scope}: #{plugin_file_path}
|
444
|
+
rescue => error
|
445
|
+
abort("Error installing plugin: #{scope}: #{plugin_file_path}\n#{error.message}")
|
442
446
|
end
|
443
447
|
end
|
444
448
|
|
@@ -517,129 +521,128 @@ def run_migrations(folder)
|
|
517
521
|
end
|
518
522
|
end
|
519
523
|
|
520
|
-
if
|
521
|
-
if not ARGV[0].nil? # argument(s) given
|
524
|
+
if not ARGV[0].nil? # argument(s) given
|
522
525
|
|
523
|
-
|
524
|
-
|
526
|
+
# Handle each task
|
527
|
+
case ARGV[0].downcase
|
525
528
|
|
526
|
-
|
527
|
-
|
529
|
+
when 'rake'
|
530
|
+
puts `rake #{ARGV[1..-1].join(' ')}`
|
528
531
|
|
529
|
-
|
530
|
-
|
532
|
+
when 'validate'
|
533
|
+
validate_plugin(ARGV[1], scope: ARGV[2], variables_file: ARGV[3])
|
531
534
|
|
532
|
-
|
533
|
-
|
535
|
+
when 'load'
|
536
|
+
# force is a boolean so if they pass 'force' it is true
|
537
|
+
# See plugins_controller.rb install for usage
|
538
|
+
load_plugin(ARGV[1], scope: ARGV[2], plugin_hash_file: ARGV[3], force: ARGV[4] == 'force')
|
534
539
|
|
535
|
-
|
536
|
-
|
540
|
+
when 'unload'
|
541
|
+
unload_plugin(ARGV[1], scope: ARGV[2])
|
537
542
|
|
538
|
-
|
539
|
-
|
543
|
+
when 'geminstall'
|
544
|
+
gem_install(ARGV[1], scope: ARGV[2])
|
540
545
|
|
541
|
-
|
542
|
-
|
546
|
+
when 'generate'
|
547
|
+
generate(ARGV[1..-1])
|
543
548
|
|
544
|
-
|
545
|
-
|
549
|
+
when 'migrate'
|
550
|
+
migrate(ARGV[1..-1])
|
546
551
|
|
547
|
-
|
548
|
-
|
552
|
+
when 'rubysloc'
|
553
|
+
puts `ruby /openc3/bin/rubysloc #{ARGV[1..-1].join(' ')}`
|
549
554
|
|
550
|
-
|
551
|
-
|
555
|
+
when 'cstol_converter'
|
556
|
+
puts `ruby /openc3/bin/cstol_converter #{ARGV[1..-1].join(' ')}`
|
552
557
|
|
553
|
-
|
554
|
-
|
558
|
+
when 'xtce_converter'
|
559
|
+
xtce_converter(ARGV[1..-1])
|
555
560
|
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
end
|
565
|
-
rescue Interrupt
|
566
|
-
exit(0)
|
561
|
+
when 'bridge'
|
562
|
+
ENV['OPENC3_NO_STORE'] = '1'
|
563
|
+
filename = ARGV[1]
|
564
|
+
filename = 'bridge.txt' unless filename
|
565
|
+
bridge = OpenC3::Bridge.new(filename)
|
566
|
+
begin
|
567
|
+
while true
|
568
|
+
sleep(1)
|
567
569
|
end
|
570
|
+
rescue Interrupt
|
571
|
+
exit(0)
|
572
|
+
end
|
568
573
|
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
574
|
+
when 'bridgesetup'
|
575
|
+
ENV['OPENC3_NO_STORE'] = '1'
|
576
|
+
filename = ARGV[1]
|
577
|
+
filename = 'bridge.txt' unless filename
|
578
|
+
unless File.exist?(filename)
|
579
|
+
OpenC3::BridgeConfig.generate_default(filename)
|
580
|
+
end
|
576
581
|
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
when 'redis'
|
581
|
-
case (ARGV[1])
|
582
|
-
when 'keys'
|
583
|
-
get_redis_keys()
|
584
|
-
when 'hget'
|
585
|
-
redis = Redis.new(url: $redis_url, username: ENV['OPENC3_REDIS_USERNAME'], password: ENV['OPENC3_REDIS_PASSWORD'])
|
586
|
-
puts JSON.parse(redis.hget(ARGV[2], ARGV[3]), :allow_nan => true, :create_additions => true)
|
587
|
-
else
|
588
|
-
puts "Unknown redis task: #{ARGV[1]}\n"
|
589
|
-
puts "Valid redis tasks: keys, hget"
|
590
|
-
end
|
582
|
+
when 'help'
|
583
|
+
print_usage()
|
591
584
|
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
585
|
+
when 'redis'
|
586
|
+
case (ARGV[1])
|
587
|
+
when 'keys'
|
588
|
+
get_redis_keys()
|
589
|
+
when 'hget'
|
590
|
+
redis = Redis.new(url: $redis_url, username: ENV['OPENC3_REDIS_USERNAME'], password: ENV['OPENC3_REDIS_PASSWORD'])
|
591
|
+
puts JSON.parse(redis.hget(ARGV[2], ARGV[3]), :allow_nan => true, :create_additions => true)
|
592
|
+
else
|
593
|
+
puts "Unknown redis task: #{ARGV[1]}\n"
|
594
|
+
puts "Valid redis tasks: keys, hget"
|
595
|
+
end
|
596
|
+
|
597
|
+
when 'removebase'
|
598
|
+
# Used to remove tool base to better support enterprise upgrade
|
599
|
+
scopes = OpenC3::ScopeModel.all
|
600
|
+
scopes.each do |scope_name, scope|
|
601
|
+
plugins = OpenC3::PluginModel.all(scope: scope_name)
|
602
|
+
plugins.each do |plugin_name, plugin|
|
603
|
+
if plugin["name"] =~ /tool-base/ and plugin["name"] !~ /enterprise/
|
604
|
+
unload_plugin(plugin_name, scope: scope_name)
|
605
|
+
end
|
606
|
+
if plugin["name"] =~ /tool-admin/ and plugin["name"] !~ /enterprise/
|
607
|
+
unload_plugin(plugin_name, scope: scope_name)
|
604
608
|
end
|
605
609
|
end
|
610
|
+
end
|
606
611
|
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
end
|
612
|
+
when 'removeenterprise'
|
613
|
+
# Used to remove enterprise plugins to better support downgrade
|
614
|
+
scopes = OpenC3::ScopeModel.all
|
615
|
+
scopes.each do |scope_name, scope|
|
616
|
+
plugins = OpenC3::PluginModel.all(scope: scope_name)
|
617
|
+
plugins.each do |plugin_name, plugin|
|
618
|
+
if plugin["name"] =~ /enterprise/
|
619
|
+
unload_plugin(plugin_name, scope: scope_name)
|
616
620
|
end
|
617
621
|
end
|
622
|
+
end
|
618
623
|
|
619
|
-
|
620
|
-
|
621
|
-
|
624
|
+
when 'destroyscope'
|
625
|
+
scope = OpenC3::ScopeModel.get_model(name: ARGV[1])
|
626
|
+
scope.destroy
|
622
627
|
|
623
|
-
|
624
|
-
|
628
|
+
when 'localinit'
|
629
|
+
OpenC3::LocalMode.local_init()
|
625
630
|
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
631
|
+
when 'initbuckets'
|
632
|
+
client = OpenC3::Bucket.getClient()
|
633
|
+
client.create(ENV['OPENC3_CONFIG_BUCKET'])
|
634
|
+
client.create(ENV['OPENC3_LOGS_BUCKET'])
|
635
|
+
client.create(ENV['OPENC3_TOOLS_BUCKET'])
|
636
|
+
client.ensure_public(ENV['OPENC3_TOOLS_BUCKET'])
|
632
637
|
|
633
|
-
|
634
|
-
|
638
|
+
when 'runmigrations'
|
639
|
+
run_migrations(ARGV[1])
|
635
640
|
|
636
|
-
|
637
|
-
print_usage()
|
638
|
-
abort("Unknown task: #{ARGV[0]}")
|
639
|
-
end
|
640
|
-
|
641
|
-
else # No arguments given
|
641
|
+
else # Unknown task
|
642
642
|
print_usage()
|
643
|
+
abort("Unknown task: #{ARGV[0]}")
|
643
644
|
end
|
644
645
|
|
645
|
-
|
646
|
+
else # No arguments given
|
647
|
+
print_usage()
|
648
|
+
end
|
@@ -78,10 +78,6 @@ PROTOCOL:
|
|
78
78
|
Protocols can be either READ, WRITE, or READ_WRITE. READ protocols act on the data
|
79
79
|
received by the interface while write acts on the data before it is sent out. READ_WRITE applies
|
80
80
|
the protocol to both reading and writing.<br/><br/>
|
81
|
-
There is only one built in protocol implemented by override_protocol.rb.
|
82
|
-
This protocol allows for Scripts to use the override_tlm() and normalize_tlm() methods to permanently
|
83
|
-
change a telemetry value. Note, this differs from set_tlm() as set_tlm() is over-written by new
|
84
|
-
incoming telemetry.<br/><br/>
|
85
81
|
For information on creating your own custom protocol please see <a href="https://openc3.com/docs/v5/protocols">https://openc3.com/docs/v5/protocols</a>
|
86
82
|
since: 4.0.0
|
87
83
|
parameters:
|
@@ -116,3 +112,25 @@ OPTION:
|
|
116
112
|
required: false
|
117
113
|
description: Parameters to pass to the option
|
118
114
|
values: .*
|
115
|
+
SECRET:
|
116
|
+
summary: Define a secret needed by this interface
|
117
|
+
description: Defines a secret for this interface and optionally assigns its value to an option
|
118
|
+
parameters:
|
119
|
+
- name: Type
|
120
|
+
required: true
|
121
|
+
description:
|
122
|
+
ENV or FILE. ENV will mount the secret into an environment variable.
|
123
|
+
FILE mounts the secret into a file.
|
124
|
+
values: .*
|
125
|
+
- name: Secret Name
|
126
|
+
required: true
|
127
|
+
description: The name of the secret to retrieve
|
128
|
+
values: .*
|
129
|
+
- name: Environment Variable of File Path
|
130
|
+
required: true
|
131
|
+
description: Environment variable name or file path to store secret
|
132
|
+
values: .*
|
133
|
+
- name: Option Name
|
134
|
+
required: false
|
135
|
+
description: Interface option to pass the secret value
|
136
|
+
values: .*
|
@@ -5,11 +5,13 @@ STATE:
|
|
5
5
|
description: Key value pairs allow for user friendly strings. For example,
|
6
6
|
you might define states for ON = 1 and OFF = 0. This allows the word ON to be
|
7
7
|
used rather than the number 1 when sending the telemetry item and allows
|
8
|
-
for much greater clarity and less chance for user error.
|
8
|
+
for much greater clarity and less chance for user error. A catch all value
|
9
|
+
of ANY applies to all other values not already defined as state values.
|
9
10
|
example: |
|
10
11
|
APPEND_ITEM ENABLE 32 UINT "Enable setting"
|
11
12
|
STATE FALSE 0
|
12
13
|
STATE TRUE 1
|
14
|
+
STATE ERROR ANY # Match all other values to ERROR
|
13
15
|
APPEND_ITEM STRING 1024 STRING "String"
|
14
16
|
STATE "NOOP" "NOOP" GREEN
|
15
17
|
STATE "ARM LASER" "ARM LASER" YELLOW
|
@@ -21,7 +23,7 @@ STATE:
|
|
21
23
|
values: .*
|
22
24
|
- name: Value
|
23
25
|
required: true
|
24
|
-
description: The numerical state value
|
26
|
+
description: The numerical state value or ANY to apply the state to all other values
|
25
27
|
values: .*
|
26
28
|
- name: Color
|
27
29
|
required: false
|
@@ -88,3 +88,21 @@ MICROSERVICE:
|
|
88
88
|
required: false
|
89
89
|
description: Name of the container
|
90
90
|
values: .+
|
91
|
+
SECRET:
|
92
|
+
summary: Define a secret needed by this microservice
|
93
|
+
description: Defines a secret for this microservice
|
94
|
+
parameters:
|
95
|
+
- name: Type
|
96
|
+
required: true
|
97
|
+
description:
|
98
|
+
ENV or FILE. ENV will mount the secret into an environment variable.
|
99
|
+
FILE mounts the secret into a file.
|
100
|
+
values: .*
|
101
|
+
- name: Secret Name
|
102
|
+
required: true
|
103
|
+
description: The name of the secret to retrieve
|
104
|
+
values: .*
|
105
|
+
- name: Environment Variable of File Path
|
106
|
+
required: true
|
107
|
+
description: Environment variable name or file path to store secret
|
108
|
+
values: .*
|
@@ -80,8 +80,8 @@ SELECT_TABLE:
|
|
80
80
|
description: The name of the existin table
|
81
81
|
values: .*
|
82
82
|
DEFAULT:
|
83
|
-
summary: Specify default values for a SINGLE row in a multi-column table
|
84
|
-
|
83
|
+
summary: Specify default values for a SINGLE row in a multi-column table
|
84
|
+
description: If you have multiple rows you need a DEFAULT line for each row.
|
85
85
|
If all your rows are identical consider using ERB as shown in the OpenC3 demo.
|
86
86
|
parameters:
|
87
87
|
- name: Default values
|
data/data/config/tool.yaml
CHANGED
@@ -47,7 +47,7 @@ TOOL:
|
|
47
47
|
values: .+
|
48
48
|
CATEGORY:
|
49
49
|
summary: Category for the tool
|
50
|
-
description: Associates the tool with a category
|
50
|
+
description: Associates the tool with a category which becomes a submenu in the Navigation menu.
|
51
51
|
parameters:
|
52
52
|
- name: Category Name
|
53
53
|
required: true
|
@@ -41,6 +41,7 @@ static ID id_method_scan = 0;
|
|
41
41
|
static ID id_method_strip = 0;
|
42
42
|
static ID id_method_to_s = 0;
|
43
43
|
static ID id_method_upcase = 0;
|
44
|
+
static ID id_method_parse_errors = 0;
|
44
45
|
|
45
46
|
/*
|
46
47
|
* Removes quotes from the given string if present.
|
@@ -103,6 +104,7 @@ static VALUE parse_loop(VALUE self, VALUE io, VALUE yield_non_keyword_lines, VAL
|
|
103
104
|
volatile VALUE ivar_keyword = Qnil;
|
104
105
|
volatile VALUE ivar_parameters = rb_ary_new();
|
105
106
|
volatile VALUE ivar_line = rb_str_new2("");
|
107
|
+
volatile VALUE errors = rb_ary_new();
|
106
108
|
|
107
109
|
rb_ivar_set(self, id_ivar_line_number, INT2FIX(0));
|
108
110
|
rb_ivar_set(self, id_ivar_keyword, ivar_keyword);
|
@@ -205,7 +207,12 @@ static VALUE parse_loop(VALUE self, VALUE io, VALUE yield_non_keyword_lines, VAL
|
|
205
207
|
rb_ary_clear(array);
|
206
208
|
rb_ary_push(array, ivar_keyword);
|
207
209
|
rb_ary_push(array, ivar_parameters);
|
208
|
-
rb_yield
|
210
|
+
line = rb_protect(rb_yield, array, &result);
|
211
|
+
if (result)
|
212
|
+
{
|
213
|
+
rb_ary_push(errors, rb_errinfo());
|
214
|
+
rb_set_errinfo(Qnil);
|
215
|
+
}
|
209
216
|
}
|
210
217
|
ivar_line = rb_str_new2("");
|
211
218
|
rb_ivar_set(self, id_ivar_line, ivar_line);
|
@@ -247,11 +254,18 @@ static VALUE parse_loop(VALUE self, VALUE io, VALUE yield_non_keyword_lines, VAL
|
|
247
254
|
rb_ary_clear(array);
|
248
255
|
rb_ary_push(array, ivar_keyword);
|
249
256
|
rb_ary_push(array, ivar_parameters);
|
250
|
-
rb_yield
|
257
|
+
line = rb_protect(rb_yield, array, &result);
|
258
|
+
if (result)
|
259
|
+
{
|
260
|
+
rb_ary_push(errors, rb_errinfo());
|
261
|
+
rb_set_errinfo(Qnil);
|
262
|
+
}
|
251
263
|
ivar_line = rb_str_new2("");
|
252
264
|
rb_ivar_set(self, id_ivar_line, ivar_line);
|
253
265
|
}
|
254
266
|
|
267
|
+
rb_funcall(self, id_method_parse_errors, 1, errors);
|
268
|
+
|
255
269
|
if (RTEST(progress_callback))
|
256
270
|
{
|
257
271
|
rb_funcall(progress_callback, id_method_call, 1, rb_float_new(1.0));
|
@@ -278,6 +292,7 @@ void Init_config_parser(void)
|
|
278
292
|
id_method_strip = rb_intern("strip");
|
279
293
|
id_method_to_s = rb_intern("to_s");
|
280
294
|
id_method_upcase = rb_intern("upcase");
|
295
|
+
id_method_parse_errors = rb_intern("parse_errors");
|
281
296
|
|
282
297
|
mOpenC3 = rb_define_module("OpenC3");
|
283
298
|
|
data/lib/openc3/api/api.rb
CHANGED
@@ -26,6 +26,7 @@ require 'openc3/api/cmd_api'
|
|
26
26
|
require 'openc3/api/config_api'
|
27
27
|
require 'openc3/api/interface_api'
|
28
28
|
require 'openc3/api/limits_api'
|
29
|
+
require 'openc3/api/metrics_api'
|
29
30
|
require 'openc3/api/offline_access_api'
|
30
31
|
require 'openc3/api/router_api'
|
31
32
|
require 'openc3/api/settings_api'
|
@@ -36,6 +36,8 @@ module OpenC3
|
|
36
36
|
'stop_raw_logging_interface',
|
37
37
|
'get_all_interface_info',
|
38
38
|
'map_target_to_interface',
|
39
|
+
'interface_cmd',
|
40
|
+
'interface_protocol_cmd'
|
39
41
|
])
|
40
42
|
|
41
43
|
# Get information about an interface
|
@@ -139,5 +141,15 @@ module OpenC3
|
|
139
141
|
end
|
140
142
|
nil
|
141
143
|
end
|
144
|
+
|
145
|
+
def interface_cmd(interface_name, cmd_name, *cmd_params, scope: $openc3_scope, token: $openc3_token)
|
146
|
+
authorize(permission: 'system_set', interface_name: interface_name, scope: scope, token: token)
|
147
|
+
InterfaceTopic.interface_cmd(interface_name, cmd_name, *cmd_params, scope: scope)
|
148
|
+
end
|
149
|
+
|
150
|
+
def interface_protocol_cmd(interface_name, cmd_name, *cmd_params, read_write: :READ_WRITE, index: -1, scope: $openc3_scope, token: $openc3_token)
|
151
|
+
authorize(permission: 'system_set', interface_name: interface_name, scope: scope, token: token)
|
152
|
+
InterfaceTopic.protocol_cmd(interface_name, cmd_name, *cmd_params, read_write: read_write, index: index, scope: scope)
|
153
|
+
end
|
142
154
|
end
|
143
155
|
end
|
@@ -0,0 +1,97 @@
|
|
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/models/metric_model'
|
20
|
+
require 'openc3/utilities/authentication'
|
21
|
+
require 'openc3/utilities/store'
|
22
|
+
|
23
|
+
module OpenC3
|
24
|
+
module Api
|
25
|
+
WHITELIST ||= []
|
26
|
+
WHITELIST.concat([
|
27
|
+
'get_metrics',
|
28
|
+
])
|
29
|
+
|
30
|
+
DELAY_METRICS = {}
|
31
|
+
DELAY_METRICS['decom_topic_delta_seconds'] = 0.0
|
32
|
+
DELAY_METRICS['interface_topic_delta_seconds'] = 0.0
|
33
|
+
DELAY_METRICS['log_topic_delta_seconds'] = 0.0
|
34
|
+
DELAY_METRICS['router_topic_delta_seconds'] = 0.0
|
35
|
+
DELAY_METRICS['text_log_topic_delta_seconds'] = 0.0
|
36
|
+
|
37
|
+
DURATION_METRICS = {}
|
38
|
+
DURATION_METRICS['decom_duration_seconds'] = 0.0
|
39
|
+
DURATION_METRICS['reducer_minute_processing_seconds'] = 0
|
40
|
+
DURATION_METRICS['reducer_hour_processing_seconds'] = 0
|
41
|
+
DURATION_METRICS['reducer_day_processing_seconds'] = 0
|
42
|
+
|
43
|
+
SUM_METRICS = {}
|
44
|
+
SUM_METRICS['cleanup_total'] = 0
|
45
|
+
SUM_METRICS['cleanup_delete_total'] = 0
|
46
|
+
SUM_METRICS['decom_total'] = 0
|
47
|
+
SUM_METRICS['decom_error_total'] = 0
|
48
|
+
SUM_METRICS['interface_cmd_total'] = 0
|
49
|
+
SUM_METRICS['interface_tlm_total'] = 0
|
50
|
+
SUM_METRICS['interface_directive_total'] = 0
|
51
|
+
SUM_METRICS['log_total'] = 0
|
52
|
+
SUM_METRICS['log_error_total'] = 0
|
53
|
+
SUM_METRICS['periodic_total'] = 0
|
54
|
+
SUM_METRICS['reducer_total'] = 0
|
55
|
+
SUM_METRICS['reducer_error_total'] = 0
|
56
|
+
SUM_METRICS['router_cmd_total'] = 0
|
57
|
+
SUM_METRICS['router_tlm_total'] = 0
|
58
|
+
SUM_METRICS['router_directive_total'] = 0
|
59
|
+
SUM_METRICS['text_log_total'] = 0
|
60
|
+
SUM_METRICS['text_log_error_total'] = 0
|
61
|
+
|
62
|
+
def get_metrics(scope: $openc3_scope, token: $openc3_token)
|
63
|
+
authorize(permission: 'system', scope: scope, token: token)
|
64
|
+
|
65
|
+
sum_metrics = SUM_METRICS.dup
|
66
|
+
duration_metrics = DURATION_METRICS.dup
|
67
|
+
delay_metrics = DELAY_METRICS.dup
|
68
|
+
|
69
|
+
metrics = MetricModel.all(scope: scope)
|
70
|
+
metrics.each do |microservice_name, metrics|
|
71
|
+
next unless metrics and metrics['values']
|
72
|
+
metrics['values'].each do |metric_name, data|
|
73
|
+
value = data['value']
|
74
|
+
if sum_metrics[metric_name]
|
75
|
+
sum_metrics[metric_name] += value
|
76
|
+
elsif duration_metrics[metric_name]
|
77
|
+
previous = duration_metrics[metric_name]
|
78
|
+
duration_metrics[metric_name] = value if value > previous
|
79
|
+
elsif delay_metrics.include?(metric_name)
|
80
|
+
previous = delay_metrics[metric_name]
|
81
|
+
delay_metrics[metric_name] = value if value > previous
|
82
|
+
else
|
83
|
+
# Ignore other metrics for now
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
result = delay_metrics
|
89
|
+
result.merge!(duration_metrics)
|
90
|
+
result.merge!(sum_metrics)
|
91
|
+
|
92
|
+
result.merge!(MetricModel.redis_metrics)
|
93
|
+
|
94
|
+
return result
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -35,6 +35,8 @@ module OpenC3
|
|
35
35
|
'start_raw_logging_router',
|
36
36
|
'stop_raw_logging_router',
|
37
37
|
'get_all_router_info',
|
38
|
+
'router_cmd',
|
39
|
+
'router_protocol_cmd'
|
38
40
|
])
|
39
41
|
|
40
42
|
# Get information about a router
|
@@ -74,7 +76,7 @@ module OpenC3
|
|
74
76
|
|
75
77
|
# Starts raw logging for a router
|
76
78
|
#
|
77
|
-
# @param router_name [String] The name of the
|
79
|
+
# @param router_name [String] The name of the router
|
78
80
|
def start_raw_logging_router(router_name = 'ALL', scope: $openc3_scope, token: $openc3_token)
|
79
81
|
authorize(permission: 'system_set', router_name: router_name, scope: scope, token: token)
|
80
82
|
if router_name == 'ALL'
|
@@ -88,7 +90,7 @@ module OpenC3
|
|
88
90
|
|
89
91
|
# Stop raw logging for a router
|
90
92
|
#
|
91
|
-
# @param router_name [String] The name of the
|
93
|
+
# @param router_name [String] The name of the router
|
92
94
|
def stop_raw_logging_router(router_name = 'ALL', scope: $openc3_scope, token: $openc3_token)
|
93
95
|
authorize(permission: 'system_set', router_name: router_name, scope: scope, token: token)
|
94
96
|
if router_name == 'ALL'
|
@@ -116,5 +118,15 @@ module OpenC3
|
|
116
118
|
info.sort! { |a, b| a[0] <=> b[0] }
|
117
119
|
info
|
118
120
|
end
|
121
|
+
|
122
|
+
def router_cmd(router_name, cmd_name, *cmd_params, scope: $openc3_scope, token: $openc3_token)
|
123
|
+
authorize(permission: 'system_set', router_name: router_name, scope: scope, token: token)
|
124
|
+
RouterTopic.router_cmd(router_name, cmd_name, *cmd_params, scope: scope)
|
125
|
+
end
|
126
|
+
|
127
|
+
def router_protocol_cmd(router_name, cmd_name, *cmd_params, read_write: :READ_WRITE, index: -1, scope: $openc3_scope, token: $openc3_token)
|
128
|
+
authorize(permission: 'system_set', router_name: router_name, scope: scope, token: token)
|
129
|
+
RouterTopic.protocol_cmd(router_name, cmd_name, *cmd_params, read_write: read_write, index: index, scope: scope)
|
130
|
+
end
|
119
131
|
end
|
120
132
|
end
|