openc3 5.5.0.pre.beta0 → 5.5.1
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.
Potentially problematic release.
This version of openc3 might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/bin/openc3cli +58 -74
- data/data/config/_canvas_values.yaml +41 -0
- data/data/config/_graph_params.yaml +25 -0
- data/data/config/graph_settings.yaml +52 -0
- data/data/config/interface_modifiers.yaml +4 -0
- data/data/config/item_modifiers.yaml +1 -1
- data/data/config/microservice.yaml +5 -1
- data/data/config/plugins.yaml +5 -0
- data/data/config/screen.yaml +44 -50
- data/data/config/settings.yaml +144 -0
- data/data/config/widgets.yaml +1744 -1491
- data/lib/openc3/api/cmd_api.rb +43 -17
- data/lib/openc3/api/tlm_api.rb +37 -4
- data/lib/openc3/bridge/bridge.rb +3 -3
- data/lib/openc3/bridge/bridge_config.rb +68 -20
- data/lib/openc3/interfaces/interface.rb +8 -0
- data/lib/openc3/microservices/decom_microservice.rb +0 -3
- data/lib/openc3/microservices/interface_microservice.rb +2 -0
- data/lib/openc3/microservices/reaction_microservice.rb +0 -1
- data/lib/openc3/models/cvt_model.rb +1 -2
- data/lib/openc3/models/interface_model.rb +5 -2
- data/lib/openc3/models/metadata_model.rb +1 -1
- data/lib/openc3/models/microservice_model.rb +7 -6
- data/lib/openc3/models/note_model.rb +1 -1
- data/lib/openc3/models/plugin_model.rb +17 -8
- data/lib/openc3/models/timeline_model.rb +1 -1
- data/lib/openc3/models/trigger_group_model.rb +1 -1
- data/lib/openc3/operators/microservice_operator.rb +2 -2
- data/lib/openc3/packets/packet_item.rb +1 -1
- data/lib/openc3/script/storage.rb +5 -5
- data/lib/openc3/streams/web_socket_client_stream.rb +0 -1
- data/lib/openc3/tools/table_manager/table_manager_core.rb +1 -2
- data/lib/openc3/utilities/aws_bucket.rb +22 -4
- data/lib/openc3/utilities/bucket_file_cache.rb +3 -2
- data/lib/openc3/utilities/bucket_utilities.rb +1 -1
- data/lib/openc3/utilities/cli_generator.rb +210 -0
- data/lib/openc3/utilities/local_mode.rb +2 -2
- data/lib/openc3/utilities/redis_secrets.rb +4 -4
- data/lib/openc3/utilities/secrets.rb +5 -5
- data/lib/openc3/utilities/target_file.rb +43 -32
- data/lib/openc3/version.rb +6 -6
- data/templates/conversion/conversion.rb +43 -0
- data/templates/limits_response/response.rb +51 -0
- data/templates/microservice/microservices/TEMPLATE/microservice.rb +62 -0
- data/templates/plugin/plugin.txt +1 -0
- data/templates/{plugin-template → target}/targets/TARGET/screens/status.txt +1 -2
- metadata +23 -16
- data/lib/openc3/models/traefik_model.rb +0 -47
- data/templates/plugin-template/plugin.txt +0 -9
- /data/templates/{plugin-template → plugin}/LICENSE.txt +0 -0
- /data/templates/{plugin-template → plugin}/README.md +0 -0
- /data/templates/{plugin-template → plugin}/Rakefile +0 -0
- /data/templates/{plugin-template → plugin}/plugin.gemspec +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/cmd_tlm/cmd.txt +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/cmd_tlm/tlm.txt +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/lib/target.rb +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/procedures/procedure.rb +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/target.txt +0 -0
    
        data/lib/openc3/api/cmd_api.rb
    CHANGED
    
    | @@ -99,6 +99,7 @@ module OpenC3 | |
| 99 99 | 
             
                # @param interface_name [String] The interface to send the raw binary
         | 
| 100 100 | 
             
                # @param data [String] The raw binary data
         | 
| 101 101 | 
             
                def send_raw(interface_name, data, scope: $openc3_scope, token: $openc3_token)
         | 
| 102 | 
            +
                  interface_name = interface_name.upcase
         | 
| 102 103 | 
             
                  authorize(permission: 'cmd_raw', interface_name: interface_name, scope: scope, token: token)
         | 
| 103 104 | 
             
                  get_interface(interface_name, scope: scope, token: token) # Check to make sure the interface exists
         | 
| 104 105 | 
             
                  InterfaceTopic.write_raw(interface_name, data, scope: scope)
         | 
| @@ -110,6 +111,8 @@ module OpenC3 | |
| 110 111 | 
             
                # @param command_name [String] Packet name of the command
         | 
| 111 112 | 
             
                # @return [Hash] command hash with last command buffer
         | 
| 112 113 | 
             
                def get_cmd_buffer(target_name, command_name, scope: $openc3_scope, token: $openc3_token)
         | 
| 114 | 
            +
                  target_name = target_name.upcase
         | 
| 115 | 
            +
                  command_name = command_name.upcase
         | 
| 113 116 | 
             
                  authorize(permission: 'cmd_info', target_name: target_name, packet_name: command_name, scope: scope, token: token)
         | 
| 114 117 | 
             
                  TargetModel.packet(target_name, command_name, type: :CMD, scope: scope)
         | 
| 115 118 | 
             
                  topic = "#{scope}__COMMAND__{#{target_name}}__#{command_name}"
         | 
| @@ -127,6 +130,7 @@ module OpenC3 | |
| 127 130 | 
             
                # @param target_name [String] Name of the target
         | 
| 128 131 | 
             
                # @return [Array<Hash>] Array of all commands as a hash
         | 
| 129 132 | 
             
                def get_all_commands(target_name, scope: $openc3_scope, token: $openc3_token)
         | 
| 133 | 
            +
                  target_name = target_name.upcase
         | 
| 130 134 | 
             
                  authorize(permission: 'cmd_info', target_name: target_name, scope: scope, token: token)
         | 
| 131 135 | 
             
                  TargetModel.packets(target_name, type: :CMD, scope: scope)
         | 
| 132 136 | 
             
                end
         | 
| @@ -137,6 +141,7 @@ module OpenC3 | |
| 137 141 | 
             
                # @param target_name [String] Name of the target
         | 
| 138 142 | 
             
                # @return [Array<String>] Array of all command packet names
         | 
| 139 143 | 
             
                def get_all_command_names(target_name, scope: $openc3_scope, token: $openc3_token)
         | 
| 144 | 
            +
                  target_name = target_name.upcase
         | 
| 140 145 | 
             
                  authorize(permission: 'cmd_info', target_name: target_name, scope: scope, token: token)
         | 
| 141 146 | 
             
                  TargetModel.packet_names(target_name, type: :CMD, scope: scope)
         | 
| 142 147 | 
             
                end
         | 
| @@ -145,23 +150,28 @@ module OpenC3 | |
| 145 150 | 
             
                #
         | 
| 146 151 | 
             
                # @since 5.0.0
         | 
| 147 152 | 
             
                # @param target_name [String] Name of the target
         | 
| 148 | 
            -
                # @param  | 
| 153 | 
            +
                # @param command_name [String] Name of the packet
         | 
| 149 154 | 
             
                # @return [Hash] Command as a hash
         | 
| 150 | 
            -
                def get_command(target_name,  | 
| 155 | 
            +
                def get_command(target_name, command_name, scope: $openc3_scope, token: $openc3_token)
         | 
| 156 | 
            +
                  target_name = target_name.upcase
         | 
| 157 | 
            +
                  command_name = command_name.upcase
         | 
| 151 158 | 
             
                  authorize(permission: 'cmd_info', target_name: target_name, scope: scope, token: token)
         | 
| 152 | 
            -
                  TargetModel.packet(target_name,  | 
| 159 | 
            +
                  TargetModel.packet(target_name, command_name, type: :CMD, scope: scope)
         | 
| 153 160 | 
             
                end
         | 
| 154 161 |  | 
| 155 162 | 
             
                # Returns a hash of the given command parameter
         | 
| 156 163 | 
             
                #
         | 
| 157 164 | 
             
                # @since 5.0.0
         | 
| 158 165 | 
             
                # @param target_name [String] Name of the target
         | 
| 159 | 
            -
                # @param  | 
| 160 | 
            -
                # @param  | 
| 166 | 
            +
                # @param command_name [String] Name of the packet
         | 
| 167 | 
            +
                # @param parameter_name [String] Name of the parameter
         | 
| 161 168 | 
             
                # @return [Hash] Command parameter as a hash
         | 
| 162 | 
            -
                def get_parameter(target_name,  | 
| 163 | 
            -
                   | 
| 164 | 
            -
                   | 
| 169 | 
            +
                def get_parameter(target_name, command_name, parameter_name, scope: $openc3_scope, token: $openc3_token)
         | 
| 170 | 
            +
                  target_name = target_name.upcase
         | 
| 171 | 
            +
                  command_name = command_name.upcase
         | 
| 172 | 
            +
                  parameter_name = parameter_name.upcase
         | 
| 173 | 
            +
                  authorize(permission: 'cmd_info', target_name: target_name, packet_name: command_name, scope: scope, token: token)
         | 
| 174 | 
            +
                  TargetModel.packet_item(target_name, command_name, parameter_name, type: :CMD, scope: scope)
         | 
| 165 175 | 
             
                end
         | 
| 166 176 |  | 
| 167 177 | 
             
                # Returns whether the specified command is hazardous
         | 
| @@ -176,35 +186,38 @@ module OpenC3 | |
| 176 186 | 
             
                  extract_string_kwargs_to_args(args, kwargs)
         | 
| 177 187 | 
             
                  case args.length
         | 
| 178 188 | 
             
                  when 1
         | 
| 179 | 
            -
                    target_name, command_name,  | 
| 189 | 
            +
                    target_name, command_name, parameters = extract_fields_from_cmd_text(args[0], scope: scope)
         | 
| 180 190 | 
             
                  when 2, 3
         | 
| 181 191 | 
             
                    target_name = args[0]
         | 
| 182 192 | 
             
                    command_name = args[1]
         | 
| 183 193 | 
             
                    if args.length == 2
         | 
| 184 | 
            -
                       | 
| 194 | 
            +
                      parameters = {}
         | 
| 185 195 | 
             
                    else
         | 
| 186 | 
            -
                       | 
| 196 | 
            +
                      parameters = args[2]
         | 
| 187 197 | 
             
                    end
         | 
| 188 198 | 
             
                  else
         | 
| 189 199 | 
             
                    # Invalid number of arguments
         | 
| 190 200 | 
             
                    raise "ERROR: Invalid number of arguments (#{args.length}) passed to get_cmd_hazardous()"
         | 
| 191 201 | 
             
                  end
         | 
| 202 | 
            +
                  target_name = target_name.upcase
         | 
| 203 | 
            +
                  command_name = command_name.upcase
         | 
| 204 | 
            +
                  parameters = parameters.transform_keys(&:upcase)
         | 
| 192 205 |  | 
| 193 206 | 
             
                  authorize(permission: 'cmd_info', target_name: target_name, packet_name: command_name, scope: scope, token: token)
         | 
| 194 207 | 
             
                  packet = TargetModel.packet(target_name, command_name, type: :CMD, scope: scope)
         | 
| 195 208 | 
             
                  return true if packet['hazardous']
         | 
| 196 209 |  | 
| 197 210 | 
             
                  packet['items'].each do |item|
         | 
| 198 | 
            -
                    next unless  | 
| 211 | 
            +
                    next unless parameters.keys.include?(item['name']) && item['states']
         | 
| 199 212 |  | 
| 200 213 | 
             
                    # States are an array of the name followed by a hash of 'value' and sometimes 'hazardous'
         | 
| 201 214 | 
             
                    item['states'].each do |name, hash|
         | 
| 202 | 
            -
                       | 
| 215 | 
            +
                      parameter_name = parameters[item['name']]
         | 
| 203 216 | 
             
                      # Remove quotes from string parameters
         | 
| 204 | 
            -
                       | 
| 217 | 
            +
                      parameter_name = parameter_name.gsub('"', '').gsub("'", '') if parameter_name.is_a?(String)
         | 
| 205 218 | 
             
                      # To be hazardous the state must be marked hazardous
         | 
| 206 219 | 
             
                      # Check if either the state name or value matches the param passed
         | 
| 207 | 
            -
                      if hash['hazardous'] && (name ==  | 
| 220 | 
            +
                      if hash['hazardous'] && (name == parameter_name || hash['value'] == parameter_name)
         | 
| 208 221 | 
             
                        return true
         | 
| 209 222 | 
             
                      end
         | 
| 210 223 | 
             
                    end
         | 
| @@ -222,6 +235,9 @@ module OpenC3 | |
| 222 235 | 
             
                #   one of {Packet::VALUE_TYPES}
         | 
| 223 236 | 
             
                # @return [Varies] value
         | 
| 224 237 | 
             
                def get_cmd_value(target_name, command_name, parameter_name, value_type = :CONVERTED, scope: $openc3_scope, token: $openc3_token)
         | 
| 238 | 
            +
                  target_name = target_name.upcase
         | 
| 239 | 
            +
                  command_name = command_name.upcase
         | 
| 240 | 
            +
                  parameter_name = parameter_name.upcase
         | 
| 225 241 | 
             
                  authorize(permission: 'cmd_info', target_name: target_name, packet_name: command_name, scope: scope, token: token)
         | 
| 226 242 | 
             
                  CommandDecomTopic.get_cmd_item(target_name, command_name, parameter_name, type: value_type, scope: scope)
         | 
| 227 243 | 
             
                end
         | 
| @@ -236,12 +252,15 @@ module OpenC3 | |
| 236 252 | 
             
                def get_cmd_time(target_name = nil, command_name = nil, scope: $openc3_scope, token: $openc3_token)
         | 
| 237 253 | 
             
                  authorize(permission: 'cmd_info', target_name: target_name, packet_name: command_name, scope: scope, token: token)
         | 
| 238 254 | 
             
                  if target_name and command_name
         | 
| 255 | 
            +
                    target_name = target_name.upcase
         | 
| 256 | 
            +
                    command_name = command_name.upcase
         | 
| 239 257 | 
             
                    time = CommandDecomTopic.get_cmd_item(target_name, command_name, 'RECEIVED_TIMESECONDS', type: :CONVERTED, scope: scope)
         | 
| 240 258 | 
             
                    [target_name, command_name, time.to_i, ((time.to_f - time.to_i) * 1_000_000).to_i]
         | 
| 241 259 | 
             
                  else
         | 
| 242 260 | 
             
                    if target_name.nil?
         | 
| 243 261 | 
             
                      targets = TargetModel.names(scope: scope)
         | 
| 244 262 | 
             
                    else
         | 
| 263 | 
            +
                      target_name = target_name.upcase
         | 
| 245 264 | 
             
                      targets = [target_name]
         | 
| 246 265 | 
             
                    end
         | 
| 247 266 | 
             
                    targets.each do |target_name|
         | 
| @@ -268,6 +287,8 @@ module OpenC3 | |
| 268 287 | 
             
                # @param command_name [String] Packet name of the command
         | 
| 269 288 | 
             
                # @return [Numeric] Transmit count for the command
         | 
| 270 289 | 
             
                def get_cmd_cnt(target_name, command_name, scope: $openc3_scope, token: $openc3_token)
         | 
| 290 | 
            +
                  target_name = target_name.upcase
         | 
| 291 | 
            +
                  command_name = command_name.upcase
         | 
| 271 292 | 
             
                  authorize(permission: 'system', target_name: target_name, packet_name: command_name, scope: scope, token: token)
         | 
| 272 293 | 
             
                  TargetModel.packet(target_name, command_name, type: :CMD, scope: scope)
         | 
| 273 294 | 
             
                  Topic.get_cnt("#{scope}__COMMAND__{#{target_name}}__#{command_name}")
         | 
| @@ -281,6 +302,8 @@ module OpenC3 | |
| 281 302 | 
             
                  authorize(permission: 'system', scope: scope, token: token)
         | 
| 282 303 | 
             
                  counts = []
         | 
| 283 304 | 
             
                  target_commands.each do |target_name, command_name|
         | 
| 305 | 
            +
                    target_name = target_name.upcase
         | 
| 306 | 
            +
                    command_name = command_name.upcase
         | 
| 284 307 | 
             
                    counts << Topic.get_cnt("#{scope}__COMMAND__{#{target_name}}__#{command_name}")
         | 
| 285 308 | 
             
                  end
         | 
| 286 309 | 
             
                  counts
         | 
| @@ -298,8 +321,8 @@ module OpenC3 | |
| 298 321 | 
             
                  when 1
         | 
| 299 322 | 
             
                    target_name, cmd_name, cmd_params = extract_fields_from_cmd_text(args[0], scope: scope)
         | 
| 300 323 | 
             
                  when 2, 3
         | 
| 301 | 
            -
                    target_name | 
| 302 | 
            -
                    cmd_name | 
| 324 | 
            +
                    target_name  = args[0]
         | 
| 325 | 
            +
                    cmd_name     = args[1]
         | 
| 303 326 | 
             
                    if args.length == 2
         | 
| 304 327 | 
             
                      cmd_params = {}
         | 
| 305 328 | 
             
                    else
         | 
| @@ -309,6 +332,9 @@ module OpenC3 | |
| 309 332 | 
             
                    # Invalid number of arguments
         | 
| 310 333 | 
             
                    raise "ERROR: Invalid number of arguments (#{args.length}) passed to #{method_name}()"
         | 
| 311 334 | 
             
                  end
         | 
| 335 | 
            +
                  target_name = target_name.upcase
         | 
| 336 | 
            +
                  cmd_name = cmd_name.upcase
         | 
| 337 | 
            +
                  cmd_params = cmd_params.transform_keys(&:upcase)
         | 
| 312 338 | 
             
                  authorize(permission: 'cmd', target_name: target_name, packet_name: cmd_name, scope: scope, token: token)
         | 
| 313 339 | 
             
                  packet = TargetModel.packet(target_name, cmd_name, type: :CMD, scope: scope)
         | 
| 314 340 |  | 
    
        data/lib/openc3/api/tlm_api.rb
    CHANGED
    
    | @@ -120,11 +120,14 @@ module OpenC3 | |
| 120 120 | 
             
                def inject_tlm(target_name, packet_name, item_hash = nil, type: :CONVERTED, scope: $openc3_scope, token: $openc3_token)
         | 
| 121 121 | 
             
                  authorize(permission: 'tlm_set', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
         | 
| 122 122 | 
             
                  type = type.to_s.intern
         | 
| 123 | 
            +
                  target_name = target_name.upcase
         | 
| 124 | 
            +
                  packet_name = packet_name.upcase
         | 
| 123 125 | 
             
                  unless CvtModel::VALUE_TYPES.include?(type)
         | 
| 124 126 | 
             
                    raise "Unknown type '#{type}' for #{target_name} #{packet_name}"
         | 
| 125 127 | 
             
                  end
         | 
| 126 128 |  | 
| 127 129 | 
             
                  if item_hash
         | 
| 130 | 
            +
                    item_hash = item_hash.transform_keys(&:upcase)
         | 
| 128 131 | 
             
                    # Check that the items exist ... exceptions are raised if not
         | 
| 129 132 | 
             
                    TargetModel.packet_items(target_name, packet_name, item_hash.keys, scope: scope)
         | 
| 130 133 | 
             
                  else
         | 
| @@ -201,6 +204,8 @@ module OpenC3 | |
| 201 204 | 
             
                # @param packet_name [String] Name of the packet
         | 
| 202 205 | 
             
                # @return [Hash] telemetry hash with last telemetry buffer
         | 
| 203 206 | 
             
                def get_tlm_buffer(target_name, packet_name, scope: $openc3_scope, token: $openc3_token)
         | 
| 207 | 
            +
                  target_name = target_name.upcase
         | 
| 208 | 
            +
                  packet_name = packet_name.upcase
         | 
| 204 209 | 
             
                  authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
         | 
| 205 210 | 
             
                  TargetModel.packet(target_name, packet_name, scope: scope)
         | 
| 206 211 | 
             
                  topic = "#{scope}__TELEMETRY__{#{target_name}}__#{packet_name}"
         | 
| @@ -222,11 +227,13 @@ module OpenC3 | |
| 222 227 | 
             
                #   of [item name, item value, item limits state] where the item limits
         | 
| 223 228 | 
             
                #   state can be one of {OpenC3::Limits::LIMITS_STATES}
         | 
| 224 229 | 
             
                def get_tlm_packet(target_name, packet_name, stale_time: 30, type: :CONVERTED, scope: $openc3_scope, token: $openc3_token)
         | 
| 230 | 
            +
                  target_name = target_name.upcase
         | 
| 231 | 
            +
                  packet_name = packet_name.upcase
         | 
| 225 232 | 
             
                  authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
         | 
| 226 233 | 
             
                  packet = TargetModel.packet(target_name, packet_name, scope: scope)
         | 
| 227 234 | 
             
                  t = _validate_tlm_type(type)
         | 
| 228 235 | 
             
                  raise ArgumentError, "Unknown type '#{type}' for #{target_name} #{packet_name}" if t.nil?
         | 
| 229 | 
            -
                  items = packet['items'].map { | item | item['name'] }
         | 
| 236 | 
            +
                  items = packet['items'].map { | item | item['name'].upcase }
         | 
| 230 237 | 
             
                  cvt_items = items.map { | item | "#{target_name}__#{packet_name}__#{item}__#{type}" }
         | 
| 231 238 | 
             
                  current_values = CvtModel.get_tlm_values(cvt_items, stale_time: stale_time, scope: scope)
         | 
| 232 239 | 
             
                  items.zip(current_values).map { | item , values | [item, values[0], values[1]]}
         | 
| @@ -246,13 +253,18 @@ module OpenC3 | |
| 246 253 | 
             
                  if !items.is_a?(Array) || !items[0].is_a?(String)
         | 
| 247 254 | 
             
                    raise ArgumentError, "items must be array of strings: ['TGT__PKT__ITEM__TYPE', ...]"
         | 
| 248 255 | 
             
                  end
         | 
| 249 | 
            -
             | 
| 250 256 | 
             
                  items.each_with_index do |item, index|
         | 
| 251 | 
            -
                    target_name, packet_name, item_name,  | 
| 257 | 
            +
                    target_name, packet_name, item_name, value_type = item.split('__')
         | 
| 258 | 
            +
                    raise ArgumentError, "items must be formatted as TGT__PKT__ITEM__TYPE" if target_name.nil? || packet_name.nil? || item_name.nil? || value_type.nil?
         | 
| 259 | 
            +
                    target_name = target_name.upcase
         | 
| 260 | 
            +
                    packet_name = packet_name.upcase
         | 
| 261 | 
            +
                    item_name = item_name.upcase
         | 
| 262 | 
            +
                    value_type = value_type.upcase
         | 
| 252 263 | 
             
                    if packet_name == 'LATEST'
         | 
| 253 264 | 
             
                      _, packet_name, _ = tlm_process_args([target_name, packet_name, item_name], 'get_tlm_values', scope: scope) # Figure out which packet is LATEST
         | 
| 254 | 
            -
                      items[index] = "#{target_name}__#{packet_name}__#{item_name}__#{item_type}" # Replace LATEST with the real packet name
         | 
| 255 265 | 
             
                    end
         | 
| 266 | 
            +
                    # Change packet_name in case of LATEST and ensure upcase
         | 
| 267 | 
            +
                    items[index] = "#{target_name}__#{packet_name}__#{item_name}__#{value_type}"
         | 
| 256 268 | 
             
                    authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
         | 
| 257 269 | 
             
                  end
         | 
| 258 270 | 
             
                  CvtModel.get_tlm_values(items, stale_time: stale_time, scope: scope)
         | 
| @@ -264,6 +276,7 @@ module OpenC3 | |
| 264 276 | 
             
                # @param target_name [String] Name of the target
         | 
| 265 277 | 
             
                # @return [Array<Hash>] Array of all telemetry packet hashes
         | 
| 266 278 | 
             
                def get_all_telemetry(target_name, scope: $openc3_scope, token: $openc3_token)
         | 
| 279 | 
            +
                  target_name = target_name.upcase
         | 
| 267 280 | 
             
                  authorize(permission: 'tlm', target_name: target_name, scope: scope, token: token)
         | 
| 268 281 | 
             
                  TargetModel.packets(target_name, type: :TLM, scope: scope)
         | 
| 269 282 | 
             
                end
         | 
| @@ -274,6 +287,7 @@ module OpenC3 | |
| 274 287 | 
             
                # @param target_name [String] Name of the target
         | 
| 275 288 | 
             
                # @return [Array<String>] Array of all telemetry packet names
         | 
| 276 289 | 
             
                def get_all_telemetry_names(target_name, scope: $openc3_scope, token: $openc3_token)
         | 
| 290 | 
            +
                  target_name = target_name.upcase
         | 
| 277 291 | 
             
                  authorize(permission: 'cmd_info', target_name: target_name, scope: scope, token: token)
         | 
| 278 292 | 
             
                  TargetModel.packet_names(target_name, type: :TLM, scope: scope)
         | 
| 279 293 | 
             
                end
         | 
| @@ -285,6 +299,8 @@ module OpenC3 | |
| 285 299 | 
             
                # @param packet_name [String] Name of the packet
         | 
| 286 300 | 
             
                # @return [Hash] Telemetry packet hash
         | 
| 287 301 | 
             
                def get_telemetry(target_name, packet_name, scope: $openc3_scope, token: $openc3_token)
         | 
| 302 | 
            +
                  target_name = target_name.upcase
         | 
| 303 | 
            +
                  packet_name = packet_name.upcase
         | 
| 288 304 | 
             
                  authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
         | 
| 289 305 | 
             
                  TargetModel.packet(target_name, packet_name, scope: scope)
         | 
| 290 306 | 
             
                end
         | 
| @@ -297,6 +313,9 @@ module OpenC3 | |
| 297 313 | 
             
                # @param item_name [String] Name of the packet
         | 
| 298 314 | 
             
                # @return [Hash] Telemetry packet item hash
         | 
| 299 315 | 
             
                def get_item(target_name, packet_name, item_name, scope: $openc3_scope, token: $openc3_token)
         | 
| 316 | 
            +
                  target_name = target_name.upcase
         | 
| 317 | 
            +
                  packet_name = packet_name.upcase
         | 
| 318 | 
            +
                  item_name = item_name.upcase
         | 
| 300 319 | 
             
                  authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
         | 
| 301 320 | 
             
                  TargetModel.packet_item(target_name, packet_name, item_name, scope: scope)
         | 
| 302 321 | 
             
                end
         | 
| @@ -316,6 +335,8 @@ module OpenC3 | |
| 316 335 |  | 
| 317 336 | 
             
                  result = {}
         | 
| 318 337 | 
             
                  packets.each do |target_name, packet_name|
         | 
| 338 | 
            +
                    target_name = target_name.upcase
         | 
| 339 | 
            +
                    packet_name = packet_name.upcase
         | 
| 319 340 | 
             
                    authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
         | 
| 320 341 | 
             
                    topic = "#{scope}__DECOM__{#{target_name}}__#{packet_name}"
         | 
| 321 342 | 
             
                    id, _ = Topic.get_newest_message(topic)
         | 
| @@ -356,6 +377,8 @@ module OpenC3 | |
| 356 377 | 
             
                # @param packet_name [String] Name of the packet
         | 
| 357 378 | 
             
                # @return [Numeric] Receive count for the telemetry packet
         | 
| 358 379 | 
             
                def get_tlm_cnt(target_name, packet_name, scope: $openc3_scope, token: $openc3_token)
         | 
| 380 | 
            +
                  target_name = target_name.upcase
         | 
| 381 | 
            +
                  packet_name = packet_name.upcase
         | 
| 359 382 | 
             
                  authorize(permission: 'system', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
         | 
| 360 383 | 
             
                  TargetModel.packet(target_name, packet_name, scope: scope)
         | 
| 361 384 | 
             
                  Topic.get_cnt("#{scope}__TELEMETRY__{#{target_name}}__#{packet_name}")
         | 
| @@ -369,6 +392,8 @@ module OpenC3 | |
| 369 392 | 
             
                  authorize(permission: 'system', scope: scope, token: token)
         | 
| 370 393 | 
             
                  counts = []
         | 
| 371 394 | 
             
                  target_packets.each do |target_name, packet_name|
         | 
| 395 | 
            +
                    target_name = target_name.upcase
         | 
| 396 | 
            +
                    packet_name = packet_name.upcase
         | 
| 372 397 | 
             
                    counts << Topic.get_cnt("#{scope}__TELEMETRY__{#{target_name}}__#{packet_name}")
         | 
| 373 398 | 
             
                  end
         | 
| 374 399 | 
             
                  counts
         | 
| @@ -380,6 +405,8 @@ module OpenC3 | |
| 380 405 | 
             
                # @param packet_name [String] Packet name
         | 
| 381 406 | 
             
                # @return [Array<String>] All of the ignored telemetry items for a packet.
         | 
| 382 407 | 
             
                def get_packet_derived_items(target_name, packet_name, scope: $openc3_scope, token: $openc3_token)
         | 
| 408 | 
            +
                  target_name = target_name.upcase
         | 
| 409 | 
            +
                  packet_name = packet_name.upcase
         | 
| 383 410 | 
             
                  authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
         | 
| 384 411 | 
             
                  packet = TargetModel.packet(target_name, packet_name, scope: scope)
         | 
| 385 412 | 
             
                  return packet['items'].select { |item| item['data_type'] == 'DERIVED' }.map { |item| item['name'] }
         | 
| @@ -413,6 +440,9 @@ module OpenC3 | |
| 413 440 | 
             
                    # Invalid number of arguments
         | 
| 414 441 | 
             
                    raise "ERROR: Invalid number of arguments (#{args.length}) passed to #{method_name}()"
         | 
| 415 442 | 
             
                  end
         | 
| 443 | 
            +
                  target_name = target_name.upcase
         | 
| 444 | 
            +
                  packet_name = packet_name.upcase
         | 
| 445 | 
            +
                  item_name = item_name.upcase
         | 
| 416 446 | 
             
                  if packet_name == 'LATEST'
         | 
| 417 447 | 
             
                    latest = -1
         | 
| 418 448 | 
             
                    TargetModel.packets(target_name, scope: scope).each do |packet|
         | 
| @@ -449,6 +479,9 @@ module OpenC3 | |
| 449 479 | 
             
                    # Invalid number of arguments
         | 
| 450 480 | 
             
                    raise "ERROR: Invalid number of arguments (#{args.length}) passed to #{method_name}()"
         | 
| 451 481 | 
             
                  end
         | 
| 482 | 
            +
                  target_name = target_name.upcase
         | 
| 483 | 
            +
                  packet_name = packet_name.upcase
         | 
| 484 | 
            +
                  item_name = item_name.upcase
         | 
| 452 485 | 
             
                  # Determine if this item exists, it will raise appropriate errors if not
         | 
| 453 486 | 
             
                  TargetModel.packet_item(target_name, packet_name, item_name, scope: scope)
         | 
| 454 487 |  | 
    
        data/lib/openc3/bridge/bridge.rb
    CHANGED
    
    | @@ -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'
         | 
| @@ -27,8 +27,8 @@ require 'openc3/bridge/bridge_router_thread' | |
| 27 27 |  | 
| 28 28 | 
             
            module OpenC3
         | 
| 29 29 | 
             
              class Bridge
         | 
| 30 | 
            -
                def initialize(filename)
         | 
| 31 | 
            -
                  @config = BridgeConfig.new(filename)
         | 
| 30 | 
            +
                def initialize(filename, existing_variables = {})
         | 
| 31 | 
            +
                  @config = BridgeConfig.new(filename, existing_variables)
         | 
| 32 32 | 
             
                  @threads = []
         | 
| 33 33 |  | 
| 34 34 | 
             
                  # Start Interface Threads
         | 
| @@ -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/utilities/logger'
         | 
| @@ -30,28 +30,55 @@ module OpenC3 | |
| 30 30 | 
             
                # @return [Hash<String, Interface>] Routers hash
         | 
| 31 31 | 
             
                attr_accessor :routers
         | 
| 32 32 |  | 
| 33 | 
            -
                def initialize(filename)
         | 
| 33 | 
            +
                def initialize(filename, existing_variables = {})
         | 
| 34 34 | 
             
                  @interfaces = {}
         | 
| 35 35 | 
             
                  @routers = {}
         | 
| 36 | 
            -
                  process_file(filename)
         | 
| 36 | 
            +
                  process_file(filename, existing_variables)
         | 
| 37 37 | 
             
                end
         | 
| 38 38 |  | 
| 39 39 | 
             
                def self.generate_default(filename)
         | 
| 40 40 | 
             
                  default_config = <<~EOF
         | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
                            # INTERFACE <Interface Name> <Interface File> <Interface Params...>
         | 
| 44 | 
            -
                            # INTERFACE <Interface Name> serial_interface.rb <Write Port> <Read Port> <Baud Rate> <Parity ODD/EVEN/NONE> <Stop Bits> <Write Timeout> <Read Timeout> <Protocol Name> <Protocol Params>
         | 
| 45 | 
            -
                            # INTERFACE <Interface Name> serial_interface.rb <Write Port> <Read Port> <Baud Rate> <Parity ODD/EVEN/NONE> <Stop Bits> <Write Timeout> <Read Timeout> BURST <Discard Leading Bytes> <Sync Pattern> <Add Sync On Write>
         | 
| 46 | 
            -
                            # INTERFACE SERIAL_INT serial_interface.rb /dev/ttyS1 /dev/ttyS1 38400 ODD 1 10.0 nil BURST 4 0xDEADBEEF
         | 
| 47 | 
            -
                            INTERFACE SERIAL_INT serial_interface.rb COM1 COM1 9600 NONE 1 10.0 nil BURST
         | 
| 41 | 
            +
                    # Write serial port name
         | 
| 42 | 
            +
                    VARIABLE write_port_name COM1
         | 
| 48 43 | 
             
                    #{'        '}
         | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 44 | 
            +
                    # Read serial port name
         | 
| 45 | 
            +
                    VARIABLE read_port_name COM1
         | 
| 46 | 
            +
                    #{'        '}
         | 
| 47 | 
            +
                    # Baud Rate
         | 
| 48 | 
            +
                    VARIABLE baud_rate 115200
         | 
| 49 | 
            +
                    #{'        '}
         | 
| 50 | 
            +
                    # Parity - NONE, ODD, or EVEN
         | 
| 51 | 
            +
                    VARIABLE parity NONE
         | 
| 52 | 
            +
                    #{'        '}
         | 
| 53 | 
            +
                    # Stop bits - 0, 1, or 2
         | 
| 54 | 
            +
                    VARIABLE stop_bits 1
         | 
| 55 | 
            +
                    #{'        '}
         | 
| 56 | 
            +
                    # Write Timeout
         | 
| 57 | 
            +
                    VARIABLE write_timeout 10.0
         | 
| 58 | 
            +
                    #{'        '}
         | 
| 59 | 
            +
                    # Read Timeout
         | 
| 60 | 
            +
                    VARIABLE read_timeout nil
         | 
| 61 | 
            +
                    #{'        '}
         | 
| 62 | 
            +
                    # Flow Control - NONE, or RTSCTS
         | 
| 63 | 
            +
                    VARIABLE flow_control NONE
         | 
| 64 | 
            +
                    #{'        '}
         | 
| 65 | 
            +
                    # Data bits per word - Typically 8
         | 
| 66 | 
            +
                    VARIABLE data_bits 8
         | 
| 67 | 
            +
                    #{'        '}
         | 
| 68 | 
            +
                    # Port to listen for connections from COSMOS - Plugin must match
         | 
| 69 | 
            +
                    VARIABLE router_port 2950
         | 
| 70 | 
            +
                    #{'        '}
         | 
| 71 | 
            +
                    # Port to listen on for connections from COSMOS. Defaults to localhost for security. Will need to be opened
         | 
| 72 | 
            +
                    # if COSMOS is on another machine.
         | 
| 73 | 
            +
                    VARIABLE router_listen_address 127.0.0.1
         | 
| 74 | 
            +
                    #{'        '}
         | 
| 75 | 
            +
                    INTERFACE SERIAL_INT serial_interface.rb <%= write_port_name %> <%= read_port_name %> <%= baud_rate %> <%= parity %> <%= stop_bits %> <%= write_timeout %> <%= read_timeout %>
         | 
| 76 | 
            +
                      OPTION FLOW_CONTROL <%= flow_control %>
         | 
| 77 | 
            +
                      OPTION DATA_BITS <%= data_bits %>
         | 
| 78 | 
            +
                    #{'        '}
         | 
| 79 | 
            +
                    ROUTER SERIAL_ROUTER tcpip_server_interface.rb <%= router_port %> <%= router_port %> 10.0 nil BURST
         | 
| 80 | 
            +
                      ROUTE SERIAL_INT
         | 
| 81 | 
            +
                      OPTION LISTEN_ADDRESS <%= router_listen_address %>
         | 
| 55 82 | 
             
                    #{'        '}
         | 
| 56 83 | 
             
                  EOF
         | 
| 57 84 |  | 
| @@ -66,18 +93,39 @@ module OpenC3 | |
| 66 93 | 
             
                # Processes a file and adds in the configuration defined in the file
         | 
| 67 94 | 
             
                #
         | 
| 68 95 | 
             
                # @param filename [String] The name of the configuration file to parse
         | 
| 69 | 
            -
                 | 
| 70 | 
            -
                #   recursively
         | 
| 71 | 
            -
                def process_file(filename, recursive = false)
         | 
| 96 | 
            +
                def process_file(filename, existing_variables = {})
         | 
| 72 97 | 
             
                  current_interface_or_router = nil
         | 
| 73 98 | 
             
                  current_type = nil
         | 
| 74 99 | 
             
                  current_interface_log_added = false
         | 
| 75 100 |  | 
| 76 101 | 
             
                  Logger.info "Processing Bridge configuration in file: #{File.expand_path(filename)}"
         | 
| 77 102 |  | 
| 103 | 
            +
                  variables = {}
         | 
| 78 104 | 
             
                  parser = ConfigParser.new
         | 
| 79 | 
            -
                  parser.parse_file(filename | 
| 105 | 
            +
                  parser.parse_file(filename,
         | 
| 106 | 
            +
                                    false,
         | 
| 107 | 
            +
                                    true,
         | 
| 108 | 
            +
                                    false) do |keyword, params|
         | 
| 80 109 | 
             
                    case keyword
         | 
| 110 | 
            +
                    when 'VARIABLE'
         | 
| 111 | 
            +
                      usage = "#{keyword} <Variable Name> <Default Value>"
         | 
| 112 | 
            +
                      parser.verify_num_parameters(2, nil, usage)
         | 
| 113 | 
            +
                      variable_name = params[0]
         | 
| 114 | 
            +
                      value = params[1..-1].join(" ")
         | 
| 115 | 
            +
                      variables[variable_name] = value
         | 
| 116 | 
            +
                      if existing_variables && existing_variables.key?(variable_name)
         | 
| 117 | 
            +
                        variables[variable_name] = existing_variables[variable_name]
         | 
| 118 | 
            +
                      end
         | 
| 119 | 
            +
                      # Ignore everything else during phase 1
         | 
| 120 | 
            +
                    end
         | 
| 121 | 
            +
                  end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                  parser = ConfigParser.new
         | 
| 124 | 
            +
                  parser.parse_file(filename, false, true, true, variables) do |keyword, params|
         | 
| 125 | 
            +
                    case keyword
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                    when 'VARIABLE'
         | 
| 128 | 
            +
                      # Ignore during this pass
         | 
| 81 129 |  | 
| 82 130 | 
             
                    when 'INTERFACE'
         | 
| 83 131 | 
             
                      usage = "INTERFACE <Name> <Filename> <Specific Parameters>"
         | 
| @@ -25,6 +25,11 @@ require 'openc3/io/raw_logger_pair' | |
| 25 25 | 
             
            require 'openc3/utilities/secrets'
         | 
| 26 26 |  | 
| 27 27 | 
             
            module OpenC3
         | 
| 28 | 
            +
              # Define a class to allow interfaces and protocols to reject commands without
         | 
| 29 | 
            +
              # disconnecting the interface
         | 
| 30 | 
            +
              class WriteRejectError < StandardError
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 28 33 | 
             
              # Defines all the attributes and methods common to all interface classes
         | 
| 29 34 | 
             
              # used by OpenC3.
         | 
| 30 35 | 
             
              class Interface
         | 
| @@ -330,6 +335,9 @@ module OpenC3 | |
| 330 335 | 
             
                  else
         | 
| 331 336 | 
             
                    @write_mutex.synchronize { yield }
         | 
| 332 337 | 
             
                  end
         | 
| 338 | 
            +
                rescue WriteRejectError => err
         | 
| 339 | 
            +
                  Logger.error("#{@name}: Write rejected by interface: #{err.message}")
         | 
| 340 | 
            +
                  raise err
         | 
| 333 341 | 
             
                rescue Exception => err
         | 
| 334 342 | 
             
                  Logger.error("#{@name}: Error writing to interface")
         | 
| 335 343 | 
             
                  disconnect()
         | 
| @@ -95,7 +95,6 @@ module OpenC3 | |
| 95 95 | 
             
                # @param log_change [Boolean] Whether to log this limits change event
         | 
| 96 96 | 
             
                def limits_change_callback(packet, item, old_limits_state, value, log_change)
         | 
| 97 97 | 
             
                  return if @cancel_thread
         | 
| 98 | 
            -
                  start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
         | 
| 99 98 | 
             
                  packet_time = packet.packet_time
         | 
| 100 99 | 
             
                  message = "#{packet.target_name} #{packet.packet_name} #{item.name} = #{value} is #{item.limits.state}"
         | 
| 101 100 | 
             
                  message << " (#{packet.packet_time.sys.formatted})" if packet_time
         | 
| @@ -136,8 +135,6 @@ module OpenC3 | |
| 136 135 | 
             
                      @logger.error e.formatted
         | 
| 137 136 | 
             
                    end
         | 
| 138 137 | 
             
                  end
         | 
| 139 | 
            -
             | 
| 140 | 
            -
                  diff = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start # seconds as a float
         | 
| 141 138 | 
             
                end
         | 
| 142 139 | 
             
              end
         | 
| 143 140 | 
             
            end
         | 
| @@ -264,7 +264,6 @@ module OpenC3 | |
| 264 264 | 
             
                      when 'trigger'
         | 
| 265 265 | 
             
                        process_enabled_trigger(data: data)
         | 
| 266 266 | 
             
                      end
         | 
| 267 | 
            -
                      current_time = Time.now.to_i
         | 
| 268 267 | 
             
                    rescue StandardError => e
         | 
| 269 268 | 
             
                      @logger.error "ReactionWorker-#{@ident} failed to evaluate kind: #{kind} data: #{data}\n#{e.formatted}"
         | 
| 270 269 | 
             
                    end
         | 
| @@ -240,11 +240,10 @@ module OpenC3 | |
| 240 240 | 
             
                # return an ordered array of hash with keys
         | 
| 241 241 | 
             
                def self._parse_item(lookups, overrides, item, scope:)
         | 
| 242 242 | 
             
                  target_name, packet_name, item_name, value_type = item.split('__')
         | 
| 243 | 
            -
                  raise ArgumentError, "items must be formatted as TGT__PKT__ITEM__TYPE" if target_name.nil? || packet_name.nil? || item_name.nil? || value_type.nil?
         | 
| 244 243 |  | 
| 245 244 | 
             
                  # We build lookup keys by including all the less formatted types to gracefully degrade lookups
         | 
| 246 245 | 
             
                  # This allows the user to specify WITH_UNITS and if there is no conversions it will simply return the RAW value
         | 
| 247 | 
            -
                  case value_type | 
| 246 | 
            +
                  case value_type
         | 
| 248 247 | 
             
                  when 'RAW'
         | 
| 249 248 | 
             
                    keys = [item_name]
         | 
| 250 249 | 
             
                  when 'CONVERTED'
         | 
| @@ -257,12 +257,15 @@ module OpenC3 | |
| 257 257 | 
             
                    @log_raw = true
         | 
| 258 258 |  | 
| 259 259 | 
             
                  when 'SECRET'
         | 
| 260 | 
            -
                    parser.verify_num_parameters(3,  | 
| 260 | 
            +
                    parser.verify_num_parameters(3, 5, "#{keyword} <Secret Type: ENV or FILE> <Secret Name> <Environment Variable Name or File Path> <Option Name (Optional)> <Secret Store Name (Optional)>")
         | 
| 261 261 | 
             
                    @secrets << parameters[0..2]
         | 
| 262 | 
            -
                    if parameters[3]
         | 
| 262 | 
            +
                    if ConfigParser.handle_nil(parameters[3])
         | 
| 263 263 | 
             
                      # Option Name, Secret Name
         | 
| 264 264 | 
             
                      @secret_options << [parameters[3], parameters[1]]
         | 
| 265 265 | 
             
                    end
         | 
| 266 | 
            +
                    if ConfigParser.handle_nil(parameters[4])
         | 
| 267 | 
            +
                      @secrets[-1] << parameters[4]
         | 
| 268 | 
            +
                    end
         | 
| 266 269 |  | 
| 267 270 | 
             
                  else
         | 
| 268 271 | 
             
                    raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Interface/Router: #{keyword} #{parameters.join(" ")}")
         | 
| @@ -69,7 +69,7 @@ module OpenC3 | |
| 69 69 | 
             
                  if @color.nil?
         | 
| 70 70 | 
             
                    @color = '#%06x' % (rand * 0xffffff)
         | 
| 71 71 | 
             
                  end
         | 
| 72 | 
            -
                  unless @color =~ /(#*)([0- | 
| 72 | 
            +
                  unless @color =~ /(#*)([0-9a-fA-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,7 +23,6 @@ | |
| 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'
         | 
| 27 26 | 
             
            require 'openc3/utilities/bucket'
         | 
| 28 27 |  | 
| 29 28 | 
             
            module OpenC3
         | 
| @@ -163,7 +162,7 @@ module OpenC3 | |
| 163 162 | 
             
                    parser.verify_num_parameters(1, 2, usage)
         | 
| 164 163 | 
             
                    begin
         | 
| 165 164 | 
             
                      @ports << [Integer(parameters[0])]
         | 
| 166 | 
            -
                    rescue  | 
| 165 | 
            +
                    rescue # In case Integer fails
         | 
| 167 166 | 
             
                      raise ConfigParser::Error.new(parser, "Port must be an integer: #{parameters[0]}", usage)
         | 
| 168 167 | 
             
                    end
         | 
| 169 168 | 
             
                    protocol = ConfigParser.handle_nil(parameters[1])
         | 
| @@ -193,8 +192,12 @@ module OpenC3 | |
| 193 192 | 
             
                    parser.verify_num_parameters(1, 1, "#{keyword} <Container Image Name>")
         | 
| 194 193 | 
             
                    @container = parameters[0]
         | 
| 195 194 | 
             
                  when 'SECRET'
         | 
| 196 | 
            -
                    parser.verify_num_parameters(3,  | 
| 197 | 
            -
                     | 
| 195 | 
            +
                    parser.verify_num_parameters(3, 4, "#{keyword} <Secret Type: ENV or FILE> <Secret Name> <Environment Variable Name or File Path> <Secret Store Name (Optional)>")
         | 
| 196 | 
            +
                    if ConfigParser.handle_nil(parameters[3])
         | 
| 197 | 
            +
                      @secrets << parameters.dup
         | 
| 198 | 
            +
                    else
         | 
| 199 | 
            +
                      @secrets << parameters[0..2]
         | 
| 200 | 
            +
                    end
         | 
| 198 201 | 
             
                  when 'ROUTE_PREFIX'
         | 
| 199 202 | 
             
                    parser.verify_num_parameters(1, 1, "#{keyword} <Route Prefix>")
         | 
| 200 203 | 
             
                    @prefix = parameters[0]
         | 
| @@ -225,7 +228,6 @@ module OpenC3 | |
| 225 228 | 
             
                    end
         | 
| 226 229 | 
             
                  end
         | 
| 227 230 | 
             
                  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 231 | 
             
                    ConfigTopic.write({ kind: 'created', type: 'microservice', name: @name, plugin: @plugin }, scope: @scope)
         | 
| 230 232 | 
             
                  end
         | 
| 231 233 | 
             
                end
         | 
| @@ -235,7 +237,6 @@ module OpenC3 | |
| 235 237 | 
             
                  @bucket.list_objects(bucket: ENV['OPENC3_CONFIG_BUCKET'], prefix: prefix).each do |object|
         | 
| 236 238 | 
             
                    @bucket.delete_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: object.key)
         | 
| 237 239 | 
             
                  end
         | 
| 238 | 
            -
                  TraefikModel.unregister_route(microservice_name: @name, port: @ports[0][0], prefix: @prefix) if @ports[0] and ports[0][0] and @prefix
         | 
| 239 240 | 
             
                  ConfigTopic.write({ kind: 'deleted', type: 'microservice', name: @name, plugin: @plugin }, scope: @scope)
         | 
| 240 241 | 
             
                rescue Exception => error
         | 
| 241 242 | 
             
                  Logger.error("Error undeploying microservice model #{@name} in scope #{@scope} due to #{error}")
         | 
| @@ -78,7 +78,7 @@ module OpenC3 | |
| 78 78 | 
             
                  if @color.nil?
         | 
| 79 79 | 
             
                    @color = '#%06x' % (rand * 0xffffff)
         | 
| 80 80 | 
             
                  end
         | 
| 81 | 
            -
                  unless @color =~ /(#*)([0- | 
| 81 | 
            +
                  unless @color =~ /(#*)([0-9a-fA-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?('#')
         |