openc3 5.2.0 → 5.3.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.
@@ -23,8 +23,10 @@
23
23
  require 'openc3'
24
24
  require 'openc3/models/microservice_model'
25
25
  require 'openc3/operators/operator'
26
+ require 'openc3/utilities/secrets'
26
27
  require 'redis'
27
28
  require 'open3'
29
+ require 'fileutils'
28
30
 
29
31
  module OpenC3
30
32
  # Creates new OperatorProcess objects based on querying the Redis key value store.
@@ -34,6 +36,7 @@ module OpenC3
34
36
  Logger.microservice_name = "MicroserviceOperator"
35
37
  super
36
38
 
39
+ @secrets = Secrets.getClient
37
40
  @microservices = {}
38
41
  @previous_microservices = {}
39
42
  @new_microservices = {}
@@ -53,6 +56,28 @@ module OpenC3
53
56
  env['OPENC3_MICROSERVICE_NAME'] = microservice_name
54
57
  container = microservice_config["container"]
55
58
  scope = microservice_name.split("__")[0]
59
+
60
+ # Setup secrets for microservice
61
+ secrets = microservice_config["secrets"]
62
+ if secrets
63
+ secrets.each do |type, secret_name, env_name_or_path|
64
+ secret_value = @secrets.get(secret_name, scope: scope)
65
+ if secret_value
66
+ case type
67
+ when 'ENV'
68
+ env[env_name_or_path] = secret_value
69
+ when 'FILE'
70
+ FileUtils.mkdir_p(File.dirname(env_name_or_path))
71
+ File.open(env_name_or_path, 'wb') do |file|
72
+ file.write(secret_value)
73
+ end
74
+ end
75
+ else
76
+ Logger.error("Microservice #{microservice_name} references unknown secret: #{secret_name}")
77
+ end
78
+ end
79
+ end
80
+
56
81
  return process_definition, work_dir, env, scope, container
57
82
  end
58
83
 
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/script/extract'
@@ -500,7 +500,20 @@ module OpenC3
500
500
  def load_utility(procedure_name)
501
501
  return start(procedure_name)
502
502
  end
503
- alias require_utility load_utility
503
+ def require_utility(procedure_name)
504
+ @require_utility_cache ||= {}
505
+ if @require_utility_cache[procedure_name]
506
+ return false
507
+ else
508
+ @require_utility_cache[procedure_name] = true
509
+ begin
510
+ return start(procedure_name)
511
+ rescue LoadError
512
+ @require_utility_cache[procedure_name] = false
513
+ raise # reraise the error
514
+ end
515
+ end
516
+ end
504
517
 
505
518
  ###########################################################################
506
519
  # Private implementation details
@@ -714,6 +727,7 @@ module OpenC3
714
727
 
715
728
  def _openc3_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate, exp_to_eval, scope: $openc3_scope, token: $openc3_token, &block)
716
729
  end_time = Time.now.sys + timeout
730
+ raise "Invalid comparison to non-ascii value" unless exp_to_eval.is_printable?
717
731
 
718
732
  while true
719
733
  work_start = Time.now.sys
@@ -792,6 +806,7 @@ module OpenC3
792
806
  # Wait on an expression to be true.
793
807
  def openc3_script_wait_implementation_expression(exp_to_eval, timeout, polling_rate, context, scope: $openc3_scope, token: $openc3_token)
794
808
  end_time = Time.now.sys + timeout
809
+ raise "Invalid comparison to non-ascii value" unless exp_to_eval.is_printable?
795
810
 
796
811
  while true
797
812
  work_start = Time.now.sys
@@ -828,6 +843,7 @@ module OpenC3
828
843
  end
829
844
 
830
845
  def check_eval(target_name, packet_name, item_name, comparison_to_eval, value, scope: $openc3_scope, token: $openc3_token)
846
+ raise "Invalid comparison to non-ascii value" unless comparison_to_eval.is_printable?
831
847
  string = "value " + comparison_to_eval
832
848
  check_str = "CHECK: #{_upcase(target_name, packet_name, item_name)} #{comparison_to_eval}"
833
849
  # Show user the check against a quoted string
@@ -76,5 +76,21 @@ module OpenC3
76
76
  sleep 1 # Give some time for the interface to shutdown
77
77
  InterfaceTopic.clear_topics(InterfaceTopic.topics(interface, scope: scope))
78
78
  end
79
+
80
+ def interface_cmd(interface_name, cmd_name, *cmd_params, scope:)
81
+ data = {}
82
+ data['cmd_name'] = cmd_name
83
+ data['cmd_params'] = cmd_params
84
+ Topic.write_topic("{#{scope}__CMD}INTERFACE__#{interface_name}", { 'interface_cmd' => JSON.generate(data, allow_nan: true) }, '*', 100)
85
+ end
86
+
87
+ def protocol_cmd(interface_name, cmd_name, *cmd_params, read_write: :READ_WRITE, index: -1, scope:)
88
+ data = {}
89
+ data['cmd_name'] = cmd_name
90
+ data['cmd_params'] = cmd_params
91
+ data['read_write'] = read_write.to_s.upcase
92
+ data['index'] = index
93
+ Topic.write_topic("{#{scope}__CMD}INTERFACE__#{interface_name}", { 'protocol_cmd' => JSON.generate(data, allow_nan: true) }, '*', 100)
94
+ end
79
95
  end
80
96
  end
@@ -88,5 +88,21 @@ module OpenC3
88
88
  sleep 1 # Give some time for the interface to shutdown
89
89
  RouterTopic.clear_topics(RouterTopic.topics(router, scope: scope))
90
90
  end
91
+
92
+ def router_cmd(router_name, cmd_name, *cmd_params, scope:)
93
+ data = {}
94
+ data['cmd_name'] = cmd_name
95
+ data['cmd_params'] = cmd_params
96
+ Topic.write_topic("{#{scope}__CMD}ROUTER__#{router_name}", { 'router_cmd' => JSON.generate(data, allow_nan: true) }, '*', 100)
97
+ end
98
+
99
+ def protocol_cmd(router_name, cmd_name, *cmd_params, read_write: :READ_WRITE, index: -1, scope:)
100
+ data = {}
101
+ data['cmd_name'] = cmd_name
102
+ data['cmd_params'] = cmd_params
103
+ data['read_write'] = read_write.to_s.upcase
104
+ data['index'] = index
105
+ Topic.write_topic("{#{scope}__CMD}ROUTER__#{router_name}", { 'protocol_cmd' => JSON.generate(data, allow_nan: true) }, '*', 100)
106
+ end
91
107
  end
92
108
  end
@@ -0,0 +1,46 @@
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
+ # This file may also be used under the terms of a commercial license
17
+ # if purchased from OpenC3, Inc.
18
+
19
+ require 'openc3/models/secret_model'
20
+ require 'openc3/utilities/secrets'
21
+
22
+ module OpenC3
23
+ class RedisSecrets < Secrets
24
+ def keys(scope:)
25
+ SecretModel.names(scope: scope)
26
+ end
27
+
28
+ def get(key, scope:)
29
+ data = SecretModel.get(name: key, scope: scope)
30
+ if data
31
+ return data['value']
32
+ else
33
+ return nil
34
+ end
35
+ end
36
+
37
+ def set(key, value, scope:)
38
+ SecretModel.set( {name: key, value: value.to_s }, scope: scope)
39
+ end
40
+
41
+ def delete(key, scope:)
42
+ model = SecretModel.get_model(name: key, scope: scope)
43
+ model.destroy if model
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,63 @@
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
+ # This file may also be used under the terms of a commercial license
17
+ # if purchased from OpenC3, Inc.
18
+
19
+ ENV['OPENC3_SECRET_BACKEND'] ||= 'redis'
20
+
21
+ module OpenC3
22
+ class Secrets
23
+ def initialize
24
+ @local_secrets = {}
25
+ end
26
+
27
+ def self.getClient
28
+ raise 'OPENC3_SECRET_BACKEND environment variable is required' unless ENV['OPENC3_SECRET_BACKEND']
29
+ secrets_class = ENV['OPENC3_SECRET_BACKEND'].capitalize + 'Secrets'
30
+ klass = OpenC3.require_class('openc3/utilities/' + secrets_class.class_name_to_filename)
31
+ klass.new
32
+ end
33
+
34
+ def keys(scope:)
35
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
36
+ end
37
+
38
+ def get(key, scope:)
39
+ return @local_secrets[key]
40
+ end
41
+
42
+ def set(key, value, scope:)
43
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
44
+ end
45
+
46
+ def delete(key, scope:)
47
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
48
+ end
49
+
50
+ def setup(secrets)
51
+ secrets.each do |type, key, data|
52
+ case type
53
+ when 'ENV'
54
+ @local_secrets[key] = ENV[data]
55
+ when 'FILE'
56
+ @local_secrets[key] = File.read(data)
57
+ else
58
+ raise "Unknown secret type: #{type}"
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,14 +1,14 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- OPENC3_VERSION = '5.2.0'
3
+ OPENC3_VERSION = '5.3.0'
4
4
  module OpenC3
5
5
  module Version
6
6
  MAJOR = '5'
7
- MINOR = '2'
7
+ MINOR = '3'
8
8
  PATCH = '0'
9
9
  OTHER = ''
10
- BUILD = '49c62512b75f45a8cbfc20a6fb5ed114bab35e23'
10
+ BUILD = 'a6b9f9a0eb9a17783ffe1e614a1da309128de52d'
11
11
  end
12
- VERSION = '5.2.0'
13
- GEM_VERSION = '5.2.0'
12
+ VERSION = '5.3.0'
13
+ GEM_VERSION = '5.3.0'
14
14
  end
@@ -1,10 +1,10 @@
1
- # OpenC3 Configuration
1
+ # OpenC3 COSMOS Plugin
2
2
 
3
3
  See the [OpenC3](https://openc3.com) documentation for all things OpenC3.
4
4
 
5
5
  ## Building the plugin
6
6
 
7
- 1. <Path to OpenC3 installation>\openc3.bat openc3 rake VERSION=X.Y.Z
7
+ 1. <Path to COSMOS installation>\openc3.bat cli rake build VERSION=X.Y.Z
8
8
  - VERSION is required
9
9
  - gem file will be built locally
10
10
 
@@ -12,4 +12,5 @@ See the [OpenC3](https://openc3.com) documentation for all things OpenC3.
12
12
 
13
13
  1. Go to localhost:2900/tools/admin
14
14
  1. Click the paperclip icon and choose your plugin.gem file
15
- 1. Click Upload
15
+ 1. Fill out plugin parameters
16
+ 1. Click Install
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openc3
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.0
4
+ version: 5.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Melton
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-12-13 00:00:00.000000000 Z
12
+ date: 2023-01-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -333,6 +333,20 @@ dependencies:
333
333
  - - "~>"
334
334
  - !ruby/object:Gem::Version
335
335
  version: '1.1'
336
+ - !ruby/object:Gem::Dependency
337
+ name: mqtt
338
+ requirement: !ruby/object:Gem::Requirement
339
+ requirements:
340
+ - - "~>"
341
+ - !ruby/object:Gem::Version
342
+ version: '0.5'
343
+ type: :runtime
344
+ prerelease: false
345
+ version_requirements: !ruby/object:Gem::Requirement
346
+ requirements:
347
+ - - "~>"
348
+ - !ruby/object:Gem::Version
349
+ version: '0.5'
336
350
  - !ruby/object:Gem::Dependency
337
351
  name: opentelemetry-sdk
338
352
  requirement: !ruby/object:Gem::Requirement
@@ -768,6 +782,7 @@ files:
768
782
  - lib/openc3/interfaces.rb
769
783
  - lib/openc3/interfaces/interface.rb
770
784
  - lib/openc3/interfaces/linc_interface.rb
785
+ - lib/openc3/interfaces/mqtt_interface.rb
771
786
  - lib/openc3/interfaces/protocols/burst_protocol.rb
772
787
  - lib/openc3/interfaces/protocols/crc_protocol.rb
773
788
  - lib/openc3/interfaces/protocols/fixed_protocol.rb
@@ -849,6 +864,7 @@ files:
849
864
  - lib/openc3/models/router_model.rb
850
865
  - lib/openc3/models/router_status_model.rb
851
866
  - lib/openc3/models/scope_model.rb
867
+ - lib/openc3/models/secret_model.rb
852
868
  - lib/openc3/models/settings_model.rb
853
869
  - lib/openc3/models/sorted_model.rb
854
870
  - lib/openc3/models/stash_model.rb
@@ -951,8 +967,10 @@ files:
951
967
  - lib/openc3/utilities/open_telemetry.rb
952
968
  - lib/openc3/utilities/process_manager.rb
953
969
  - lib/openc3/utilities/quaternion.rb
970
+ - lib/openc3/utilities/redis_secrets.rb
954
971
  - lib/openc3/utilities/ruby_lex_utils.rb
955
972
  - lib/openc3/utilities/s3_autoload.rb
973
+ - lib/openc3/utilities/secrets.rb
956
974
  - lib/openc3/utilities/simulated_target.rb
957
975
  - lib/openc3/utilities/sleeper.rb
958
976
  - lib/openc3/utilities/store.rb