openc3 5.4.2 → 5.5.0.pre.beta0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08e9c285070449047388f035c8c56522154ed54cd9e075dc3b52e87f17a7ff0e'
4
- data.tar.gz: d52d4c20ffd7f7ea1593d19df3be807d7dc4cc787e30390d11f8c1b90103c186
3
+ metadata.gz: 47eef747a6f82da0e4cdf93863f00357e07be1002d58762c4345c611e53da9a5
4
+ data.tar.gz: 6b6b804cac37eab03765a619aedd6ec4e6d4e8a9dfe5048507d23bd9c0987542
5
5
  SHA512:
6
- metadata.gz: 5e242af794c1263642f951c46867ce5fa543ccef505c60c0d6a4015c91503acf8d62b3b7b8dd40b91ec4c252013b4a40eec21d0bb3055bc5f6ae11e370c48fbe
7
- data.tar.gz: 06b2ad289fcd4bfbfa23a896469b1d9d4b55b017e4535eb060a101147b4b757535f071dd622121f78923a2d0e1923795e109b94d3c6917933e0ce74e11c586cd
6
+ metadata.gz: 9f862cfdc31ded71fe8eaa59f8771ccb88d45b0363fa17636c6ed8a0c1cfcb30343f4850b57fba89dc9fd221e9a70cb7af7524081bb4d7f24e8d263c816b3879
7
+ data.tar.gz: 3604545c30b970d8ed6e6c0bf69c8d6ba0eeffefd3cb0c043d65ea140dfb15936bcd3d9ffb94bdb21493d40c05213838bdf7df215ee12597e41275cc903d16ee
data/Gemfile CHANGED
@@ -6,13 +6,8 @@ gem 'ruby-termios', '>= 0.9' if RbConfig::CONFIG['target_os'] !~ /mswin|mingw|cy
6
6
 
7
7
  gemspec :name => 'openc3'
8
8
 
9
- # unless ENV['JENKINS_HOME']
10
- # # Example of how to use a local branch (doesn't work on Jenkins)
11
- # # You also need to set "bundle config local.mock_redis <LOCAL PATH TO CHECKED OUT GEM>"
12
- # # For example: bundle config local.mock_redis C:/_Programs/oss/mock_redis
13
- # # Make sure the local copy is checked out to the specified branch
14
- # # Delete the config: bundle config --delete local.mock_redis
15
- # group :development do
16
- # gem 'mock_redis', github: 'jasonatball/mock_redis', branch: 'master'
17
- # end
18
- # end
9
+ # Include the rails gems for the convenience of custom microservice plugins
10
+ gem 'rails', '~> 7.0.0'
11
+ gem 'bootsnap', '>= 1.9.3', require: false
12
+ gem 'rack-cors', '~> 1.1'
13
+ gem 'tzinfo-data'
data/bin/openc3cli CHANGED
@@ -43,6 +43,8 @@ require 'redis'
43
43
  require 'erb'
44
44
  require 'pp'
45
45
  # require 'psych' # Psych code is commented out
46
+ require "irb"
47
+ require "irb/completion"
46
48
 
47
49
  $redis_url = "redis://#{ENV['OPENC3_REDIS_HOSTNAME']}:#{ENV['OPENC3_REDIS_PORT']}"
48
50
  # Initialize the connection to the bucket library
@@ -64,13 +66,14 @@ def print_usage
64
66
  puts "Usage:"
65
67
  puts " cli help # Displays this information"
66
68
  puts " cli rake # Runs rake in the local directory"
69
+ puts " cli irb # Runs irb in the local directory"
67
70
  puts " cli validate /PATH/FILENAME.gem SCOPE variables.txt # Validate a COSMOS plugin gem file"
68
71
  puts " cli load /PATH/FILENAME.gem SCOPE variables.txt # Loads a COSMOS plugin gem file"
69
72
  puts " cli generate plugin PLUGIN_NAME # Generate a COSMOS plugin"
70
73
  puts " #{MIGRATE_PARSER}"
71
74
  puts " cli bridge CONFIG_FILENAME # Run COSMOS host bridge"
72
75
  puts " cli bridgesetup CONFIG_FILENAME # Create a default config file"
73
- puts " cli geminstall GEMFILENAME SCOPE # Install loaded gem to /gems"
76
+ puts " cli geminstall GEMFILENAME SCOPE # Install loaded gem to /gems"
74
77
  puts " cli rubysloc # Counts Ruby SLOC recursively. Run with --help for more info."
75
78
  puts " cli xtce_converter # Convert to and from the XTCE format. Run with --help for more info."
76
79
  puts " cli cstol_converter # Converts CSTOL files (.prc) to COSMOS. Run with --help for more info."
@@ -526,6 +529,10 @@ if not ARGV[0].nil? # argument(s) given
526
529
  # Handle each task
527
530
  case ARGV[0].downcase
528
531
 
532
+ when 'irb'
533
+ ARGV.clear
534
+ IRB.start
535
+
529
536
  when 'rake'
530
537
  puts `rake #{ARGV[1..-1].join(' ')}`
531
538
 
@@ -27,7 +27,8 @@ tcpip_client_interface.rb:
27
27
  - name: Protocol Type
28
28
  required: true
29
29
  description: Protocol to apply on the interface data
30
- values:
30
+ # prettier-ignore
31
+ values:
31
32
  <%= MetaConfigParser.load('protocols.yaml').to_meta_config_yaml(8) %>
32
33
  tcpip_server_interface.rb:
33
34
  parameters:
@@ -52,7 +53,8 @@ tcpip_server_interface.rb:
52
53
  - name: Protocol Type
53
54
  required: true
54
55
  description: Protocol to apply on the interface data
55
- values:
56
+ # prettier-ignore
57
+ values:
56
58
  <%= MetaConfigParser.load('protocols.yaml').to_meta_config_yaml(8) %>
57
59
  udp_interface.rb:
58
60
  description: The UDP interface uses UDP packets to send and receive telemetry
@@ -142,73 +144,6 @@ serial_interface.rb:
142
144
  - name: Protocol Type
143
145
  required: true
144
146
  description: Protocol to apply on the interface data
145
- values:
147
+ # prettier-ignore
148
+ values:
146
149
  <%= MetaConfigParser.load('protocols.yaml').to_meta_config_yaml(8) %>
147
- cmd_tlm_server_interface.rb:
148
- description: Provides a connection to the OpenC3 Command and Telemetry Server.
149
- This allows scripts and other OpenC3 tools to send commands to the CmdTlmServer
150
- to enable and disable logging. It also allows scripts and other tools to
151
- receive a OpenC3 version information packet and a limits change packet which
152
- is sent when any telemetry items change limits states. The CmdTlmServer
153
- interface can be used by any OpenC3 configuration.
154
- linc_interface.rb:
155
- description: The LINC interface uses a single TCPIP socket to talk to a Ball
156
- Aerospace LINC Labview target.
157
- parameters:
158
- - name: Host
159
- required: true
160
- description: Machine name to connect to. Can be either a named
161
- machine (DNS entry) or IP address.
162
- values: .+
163
- - name: Port
164
- required: true
165
- description: Port to write commands to and read telemetry from
166
- values: \d{2,5}
167
- - name: Handshake Enabled
168
- required: false
169
- description: Enable command handshaking where commands block until the
170
- corresponding handshake message is received. Default is true.
171
- values: ["true", "false"]
172
- - name: Response Timeout
173
- required: false
174
- description: Number of seconds to wait for a handshaking response.
175
- Default is 5 seconds
176
- values: \d+
177
- - name: Read Timeout
178
- required: true
179
- description: Number of seconds to wait before aborting the read.
180
- Pass 'nil' to block on read. Default is nil.
181
- values: .+
182
- - name: Write Timeout
183
- required: true
184
- description: Number of seconds to wait before aborting the write.
185
- Pass 'nil' to block on write. Default is 5 seconds.
186
- values: .+
187
- - name: Length Bit Offset
188
- required: false
189
- description: The bit offset of the length field. Every packet using this
190
- interface must have the same structure such that the length field is the
191
- same size at the same location. Default is 0.
192
- values: \d+
193
- - name: Length Bit Size
194
- required: false
195
- description: The size in bits of the length field. Default is 16 bits.
196
- values: \d+
197
- - name: Length Value Offset
198
- required: false
199
- description: The offset to apply to the length field value. For example if
200
- the length field indicates packet length minus one, this value should be one.
201
- Default is 4.
202
- values: \d+
203
- - name: GUID Fieldname
204
- required: false
205
- description: Fieldname of the GUID field. Default is 'HDR_GUID'.
206
- values: .+
207
- - name: Length Endianness
208
- required: false
209
- description: The endianness of the length field. Default is BIG_ENDIAN.
210
- values: ["BIG_ENDIAN", "LITTLE_ENDIAN"]
211
- - name: Length Fieldname
212
- required: false
213
- description: Fieldname of the length field. Defaults is 'HDR_LENGTH'.
214
- values: .+
@@ -41,29 +41,6 @@ DISABLE_DISCONNECT:
41
41
  Use this keyword to prevent the user from disconnecting from the interface.
42
42
  This is typically used in a 'production' environment where you would not want
43
43
  the user to inadvertantly disconnect from a target.
44
- LOG:
45
- summary: Enable logging on the interface by the specified log writer
46
- description:
47
- LOG is only required if you want a log writer other than the default
48
- to log commands and telemetry on this interface
49
- warning: Choosing a custom log writer can prevent OpenC3 from reading back your log files
50
- parameters:
51
- - name: Name
52
- required: true
53
- description: Log writer name as defined by PACKET_LOG_WRITER
54
- values: \D\S*
55
- LOG_STORED:
56
- summary: Enable logging of stored telemetry on the interface by the specified log writer
57
- description:
58
- LOG_STORED allows you to specify a different log writer for stored telemetry
59
- (telemetry which has the 'stored' flag set in the packet). By default the stored telemetry
60
- is intermingled in the normal log file.
61
- warning: Choosing a custom log writer can prevent OpenC3 from reading back your log files
62
- parameters:
63
- - name: Name
64
- required: true
65
- description: Log writer name as defined by PACKET_LOG_WRITER
66
- values: \D\S*
67
44
  DONT_LOG:
68
45
  summary: Disable logging commands and telemetry on this interface
69
46
  LOG_RAW:
@@ -106,3 +106,11 @@ MICROSERVICE:
106
106
  required: true
107
107
  description: Environment variable name or file path to store secret
108
108
  values: .*
109
+ ROUTE_PREFIX:
110
+ summary: Prefix of route
111
+ description: Prefix of route to the microservice to expose externally with Traefik
112
+ parameters:
113
+ - name: Route Prefix
114
+ required: true
115
+ description: Route prefix. Must be unique across all scopes. Something like /myprefix
116
+ values: .*
@@ -156,6 +156,7 @@ TARGET:
156
156
  values: \d+
157
157
  TARGET_MICROSERVICE:
158
158
  summary: Breaks a target microservice out into its own process.
159
+ description:
159
160
  Can be used to give more resources to processing that is falling behind.
160
161
  If defined multiple times for the same type, will create multiple processes.
161
162
  Each process can be given specific packets to process with the PACKET keyword.
@@ -162,26 +162,6 @@ TITLE:
162
162
  required: true
163
163
  description: Text to display above the horizontal line
164
164
  values: .*
165
- # SPACER:
166
- # summary: Inserts a spacer into a layout. This can be used to
167
- # separate or align other widgets.
168
- # parameters:
169
- # - name: Width
170
- # required: true
171
- # description: The width of the spacer in pixels.
172
- # values: .*
173
- # - name: Height
174
- # required: true
175
- # description: The height of the spacer in pixels.
176
- # values: .*
177
- # - name: Horizontal Policy
178
- # required: false
179
- # description: The horizontal size policy of the spacer. Default is MINIMUM.
180
- # values: <%= %w(FIXED MINIMUM MAXIMUM PREFERRED EXPANDING MINIMUMEXPANDING IGNORED) %>
181
- # - name: Vertical Policy
182
- # required: false
183
- # description: The vertical size policy of the spacer. Default is MINIMUM.
184
- # values: <%= %w(FIXED MINIMUM MAXIMUM PREFERRED EXPANDING MINIMUMEXPANDING IGNORED) %>
185
165
  ARRAY:
186
166
  summary: Displays ARRAY data organized into rows and space separated
187
167
  parameters:
@@ -303,7 +283,8 @@ BLOCK:
303
283
  # values: .*
304
284
  FORMATVALUE:
305
285
  summary: Displays a box with a formatted value
306
- description: Data is formatted by the specified string rather than by a format string given in
286
+ description:
287
+ Data is formatted by the specified string rather than by a format string given in
307
288
  the telemetry definition files. The white portion of the box darkens to gray
308
289
  while the value remains stagnant, then brightens to white each time the value
309
290
  changes. Additionally the value is colored based on the items limits state
@@ -615,7 +596,8 @@ LABELVALUERANGEBAR:
615
596
  # values: .*
616
597
  LED:
617
598
  summary: Displays a LED which changes color based on telemetry values
618
- description: By default TRUE is green and FALSE is red and all other values are black.
599
+ description:
600
+ By default TRUE is green and FALSE is red and all other values are black.
619
601
  Additional values can be added by using the LED_COLOR setting. For example
620
602
  LED INST PARAMS VALUE3 RAW can be followed by SETTING LED_COLOR 0 GREEN,
621
603
  SETTING LED_COLOR 1 RED, and SETTING LED_COLOR ANY ORANGE.
@@ -1153,7 +1135,8 @@ TEXTBOX:
1153
1135
  # values: .*
1154
1136
  VALUE:
1155
1137
  summary: Displays a box with a telemetry item value
1156
- description: The white portion of the box darkens to gray while the value remains stagnant, then
1138
+ description:
1139
+ The white portion of the box darkens to gray while the value remains stagnant, then
1157
1140
  brightens to white each time the value changes. Additionally the value is
1158
1141
  colored based on the items limits state (Red for example if it is out of limits).
1159
1142
  parameters:
@@ -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/packets/binary_accessor'
@@ -28,7 +28,7 @@ class String
28
28
  # The printable range of ASCII characters
29
29
  PRINTABLE_RANGE = 32..126
30
30
  # Regular expression to identify a character that is not in the printable range
31
- NON_PRINTABLE_REGEX = /[^\s -~]/
31
+ NON_PRINTABLE_REGEX = /[^\s!-~]/
32
32
  # Regular expression to identify a String as a floating point number
33
33
  FLOAT_CHECK_REGEX = /\A\s*[-+]?\d*\.\d+\s*\z/
34
34
  # Regular expression to identify a String as a floating point number in
@@ -56,11 +56,15 @@ end
56
56
 
57
57
  class String
58
58
  NON_ASCII_PRINTABLE = /[^\x21-\x7e\s]/
59
-
59
+ NON_UTF8_PRINTABLE = /[\x00-\x08\x0E-\x1F\x7F]/
60
60
  def as_json(options = nil)
61
61
  as_utf8 = self.dup.force_encoding('UTF-8')
62
62
  if as_utf8.valid_encoding?
63
- return as_utf8
63
+ if as_utf8 =~ NON_UTF8_PRINTABLE
64
+ return self.to_json_raw_object
65
+ else
66
+ return as_utf8
67
+ end
64
68
  else
65
69
  return self.to_json_raw_object
66
70
  end
@@ -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/microservices/microservice'
@@ -31,6 +31,15 @@ module OpenC3
31
31
 
32
32
  def run
33
33
  Dir.chdir @work_dir
34
+ begin
35
+ if @config["cmd"][0] != 'ruby'
36
+ # Try to make sure the cmd is executable
37
+ FileUtils.chmod 0777, @config["cmd"][0]
38
+ end
39
+ rescue Exception
40
+ # Its ok if this fails
41
+ end
42
+
34
43
  # Fortify: Process Control
35
44
  # This is dangerous! However, plugins need to be able to run whatever they want.
36
45
  # Only admins can install plugins and they need to be vetted for content.
@@ -42,22 +42,24 @@ module OpenC3
42
42
 
43
43
  # Set an item in the current value table
44
44
  def self.set_item(target_name, packet_name, item_name, value, type:, scope: $openc3_scope)
45
+ hash = JSON.parse(Store.hget("#{scope}__tlm__#{target_name}", packet_name), :allow_nan => true, :create_additions => true)
45
46
  case type
46
47
  when :WITH_UNITS
47
- field = "#{item_name}__U"
48
- value = value.to_s # WITH_UNITS should always be a string
48
+ hash["#{item_name}__U"] = value.to_s # WITH_UNITS should always be a string
49
49
  when :FORMATTED
50
- field = "#{item_name}__F"
51
- value = value.to_s # FORMATTED should always be a string
50
+ hash["#{item_name}__F"] = value.to_s # FORMATTED should always be a string
52
51
  when :CONVERTED
53
- field = "#{item_name}__C"
52
+ hash["#{item_name}__C"] = value
54
53
  when :RAW
55
- field = item_name
54
+ hash[item_name] = value
55
+ when :ALL
56
+ hash["#{item_name}__U"] = value.to_s # WITH_UNITS should always be a string
57
+ hash["#{item_name}__F"] = value.to_s # FORMATTED should always be a string
58
+ hash["#{item_name}__C"] = value
59
+ hash[item_name] = value
56
60
  else
57
61
  raise "Unknown type '#{type}' for #{target_name} #{packet_name} #{item_name}"
58
62
  end
59
- hash = JSON.parse(Store.hget("#{scope}__tlm__#{target_name}", packet_name), :allow_nan => true, :create_additions => true)
60
- hash[field] = value
61
63
  Store.hset("#{scope}__tlm__#{target_name}", packet_name, JSON.generate(hash.as_json(:allow_nan => true)))
62
64
  end
63
65
 
@@ -69,7 +69,7 @@ module OpenC3
69
69
  if @color.nil?
70
70
  @color = '#%06x' % (rand * 0xffffff)
71
71
  end
72
- unless @color =~ /(#*)([0-9,a-f,A-f]{6})/
72
+ unless @color =~ /(#*)([0-9,a-f,A-F]{6})/
73
73
  raise SortedInputError.new "invalid color, must be in hex format, e.g. #FF0000"
74
74
  end
75
75
  @color = "##{@color}" unless @color.start_with?('#')
@@ -23,6 +23,7 @@
23
23
  require 'openc3/top_level'
24
24
  require 'openc3/models/model'
25
25
  require 'openc3/models/metric_model'
26
+ require 'openc3/models/traefik_model'
26
27
  require 'openc3/utilities/bucket'
27
28
 
28
29
  module OpenC3
@@ -41,6 +42,7 @@ module OpenC3
41
42
  attr_accessor :ports
42
43
  attr_accessor :parent
43
44
  attr_accessor :secrets
45
+ attr_accessor :prefix
44
46
 
45
47
  # NOTE: The following three class methods are used by the ModelController
46
48
  # and are reimplemented to enable various Model class methods to work
@@ -99,6 +101,7 @@ module OpenC3
99
101
  plugin: nil,
100
102
  needs_dependencies: false,
101
103
  secrets: [],
104
+ prefix: nil,
102
105
  scope:
103
106
  )
104
107
  parts = name.split("__")
@@ -122,6 +125,7 @@ module OpenC3
122
125
  @container = container
123
126
  @needs_dependencies = needs_dependencies
124
127
  @secrets = secrets
128
+ @prefix = prefix
125
129
  @bucket = Bucket.getClient()
126
130
  end
127
131
 
@@ -141,7 +145,8 @@ module OpenC3
141
145
  'updated_at' => @updated_at,
142
146
  'plugin' => @plugin,
143
147
  'needs_dependencies' => @needs_dependencies,
144
- 'secrets' => @secrets.as_json(*a)
148
+ 'secrets' => @secrets.as_json(*a),
149
+ 'prefix' => @prefix
145
150
  }
146
151
  end
147
152
 
@@ -190,6 +195,9 @@ module OpenC3
190
195
  when 'SECRET'
191
196
  parser.verify_num_parameters(3, 3, "#{keyword} <Secret Type: ENV or FILE> <Secret Name> <Environment Variable Name or File Path>")
192
197
  @secrets << parameters.dup
198
+ when 'ROUTE_PREFIX'
199
+ parser.verify_num_parameters(1, 1, "#{keyword} <Route Prefix>")
200
+ @prefix = parameters[0]
193
201
  else
194
202
  raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Microservice: #{keyword} #{parameters.join(" ")}")
195
203
  end
@@ -214,9 +222,12 @@ module OpenC3
214
222
  end
215
223
  unless validate_only
216
224
  @bucket.put_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: key, body: data)
217
- ConfigTopic.write({ kind: 'created', type: 'microservice', name: @name, plugin: @plugin }, scope: @scope)
218
225
  end
219
226
  end
227
+ unless validate_only
228
+ TraefikModel.register_route(microservice_name: @name, port: @ports[0][0], prefix: @prefix) if @ports[0] and ports[0][0] and @prefix
229
+ ConfigTopic.write({ kind: 'created', type: 'microservice', name: @name, plugin: @plugin }, scope: @scope)
230
+ end
220
231
  end
221
232
 
222
233
  def undeploy
@@ -224,6 +235,7 @@ module OpenC3
224
235
  @bucket.list_objects(bucket: ENV['OPENC3_CONFIG_BUCKET'], prefix: prefix).each do |object|
225
236
  @bucket.delete_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: object.key)
226
237
  end
238
+ TraefikModel.unregister_route(microservice_name: @name, port: @ports[0][0], prefix: @prefix) if @ports[0] and ports[0][0] and @prefix
227
239
  ConfigTopic.write({ kind: 'deleted', type: 'microservice', name: @name, plugin: @plugin }, scope: @scope)
228
240
  rescue Exception => error
229
241
  Logger.error("Error undeploying microservice model #{@name} in scope #{@scope} due to #{error}")
@@ -63,20 +63,12 @@ module OpenC3
63
63
  # END NOTE
64
64
 
65
65
  # Loops over all items and returns objects that match a key value pair
66
- def self.filter(key, value, scope:, use_regex: false)
66
+ def self.filter(key, value, scope:, substr: false)
67
67
  filtered = {}
68
68
  results = all(scope: scope)
69
- regex = nil
70
- regex = Regexp.new(value) if use_regex
71
69
  results.each do |name, result|
72
- if regex
73
- if result[key] =~ regex
74
- filtered[name] = result
75
- end
76
- else
77
- if result[key] == value
78
- filtered[name] = result
79
- end
70
+ if result[key] == value || (substr && result[key].include?(value))
71
+ filtered[name] = result
80
72
  end
81
73
  end
82
74
  return filtered
@@ -78,7 +78,7 @@ module OpenC3
78
78
  if @color.nil?
79
79
  @color = '#%06x' % (rand * 0xffffff)
80
80
  end
81
- unless @color =~ /(#*)([0-9,a-f,A-f]{6})/
81
+ unless @color =~ /(#*)([0-9,a-f,A-F]{6})/
82
82
  raise SortedInputError.new "invalid color, must be in hex format, e.g. #FF0000"
83
83
  end
84
84
  @color = "##{@color}" unless @color.start_with?('#')
@@ -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/models/model'
@@ -91,11 +91,10 @@ module OpenC3
91
91
  if color.nil?
92
92
  color = '#%06x' % (rand * 0xffffff)
93
93
  end
94
- valid_color = color =~ /(#*)([0-9,a-f,A-f]{6})/
94
+ valid_color = color =~ /[0-9,a-f,A-F]{6}/
95
95
  if valid_color.nil?
96
96
  raise RuntimeError.new "invalid color but in hex format. #FF0000"
97
97
  end
98
-
99
98
  unless color.start_with?('#')
100
99
  color = "##{color}"
101
100
  end
@@ -0,0 +1,47 @@
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/utilities/store'
20
+
21
+ module OpenC3
22
+ class TraefikModel
23
+ def self.register_route(microservice_name:, port:, prefix:, priority: 20)
24
+ prefix = '/' + prefix unless prefix[0] == '/'
25
+ if ENV['KUBERNETES_SERVICE_HOST']
26
+ url = "http://#{microservice_name.gsub('__', '-')}:#{port}"
27
+ else
28
+ url = "http://openc3-operator:#{port}"
29
+ end
30
+ service_name = microservice_name
31
+ router_name = microservice_name
32
+ Store.set("traefik/http/services/#{service_name}/loadbalancer/servers/0/url", url)
33
+ Store.set("traefik/http/routers/#{router_name}/service", service_name)
34
+ Store.set("traefik/http/routers/#{router_name}/priority", priority)
35
+ Store.set("traefik/http/routers/#{router_name}/rule", "PathPrefix(`#{prefix}`)")
36
+ end
37
+
38
+ def self.unregister_route(microservice_name:)
39
+ service_name = microservice_name
40
+ router_name = microservice_name
41
+ Store.del("traefik/http/routers/#{router_name}/rule")
42
+ Store.del("traefik/http/routers/#{router_name}/priority")
43
+ Store.del("traefik/http/routers/#{router_name}/service")
44
+ Store.del("traefik/http/services/#{service_name}/loadbalancer/servers/0/url")
45
+ end
46
+ end
47
+ end
@@ -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/models/model'
@@ -92,11 +92,10 @@ module OpenC3
92
92
  if color.nil?
93
93
  color = '#%06x' % (rand * 0xffffff)
94
94
  end
95
- valid_color = color =~ /(#*)([0-9,a-f,A-f]{6})/
95
+ valid_color = color =~ /[0-9,a-f,A-F]{6}/
96
96
  if valid_color.nil?
97
97
  raise TriggerGroupInputError.new "invalid color must be in hex format. #FF0000"
98
98
  end
99
-
100
99
  unless color.start_with?('#')
101
100
  color = "##{color}"
102
101
  end
@@ -31,6 +31,7 @@ require 'openc3/script/limits'
31
31
  require 'openc3/script/exceptions'
32
32
  require 'openc3/script/script_runner'
33
33
  require 'openc3/script/storage'
34
+ require 'openc3/script/web_socket_api'
34
35
  require 'openc3/utilities/authentication'
35
36
 
36
37
  $api_server = nil
@@ -99,6 +100,15 @@ module OpenC3
99
100
  # NOOP
100
101
  end
101
102
 
103
+ def openc3_script_sleep(sleep_time = nil)
104
+ if sleep_time
105
+ sleep(sleep_time)
106
+ else
107
+ prompt("Press any key to continue...")
108
+ end
109
+ return false
110
+ end
111
+
102
112
  def ask_string(question, blank_or_default = false, password = false)
103
113
  answer = ''
104
114
  default = ''
@@ -65,7 +65,7 @@ module OpenC3
65
65
 
66
66
  endpoint = "/openc3-api/storage/upload/#{upload_path}"
67
67
  result = _get_presigned_request(endpoint, scope: scope)
68
- OpenC3::Logger.info "Writing #{upload_path} at #{result['url']}"
68
+ OpenC3::Logger.info "Writing #{upload_path}"
69
69
 
70
70
  # Try to put the file
71
71
  begin
@@ -104,11 +104,12 @@ module OpenC3
104
104
  if part == "targets_modified" and ENV['OPENC3_LOCAL_MODE']
105
105
  local_file = OpenC3::LocalMode.open_local_file(path, scope: scope)
106
106
  if local_file
107
+ OpenC3::Logger.info "Reading local #{scope}/#{path}"
107
108
  file = Tempfile.new('target', binmode: true)
108
109
  file.write(local_file.read)
109
110
  local_file.close
110
111
  file.rewind
111
- return file if local_file
112
+ return file
112
113
  end
113
114
  end
114
115
 
@@ -133,7 +134,7 @@ module OpenC3
133
134
 
134
135
  endpoint = "/openc3-api/storage/download/#{scope}/#{path}"
135
136
  result = _get_presigned_request(endpoint, scope: scope)
136
- OpenC3::Logger.info "Reading #{scope}/#{path} at #{result['url']}"
137
+ OpenC3::Logger.info "Reading #{scope}/#{path}"
137
138
 
138
139
  # Try to get the file
139
140
  uri = _get_uri(result['url'])