openc3-cosmos-tool-docs 6.3.0 → 6.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/tools/staticdocs/404.html +1 -1
- data/tools/staticdocs/assets/images/cosmos-containers-7ecd745840fcff307f0fec01ac4d88a8fa76d531abeae407fee0e508f50a487c.png +0 -0
- data/tools/staticdocs/assets/images/cosmos-images-8e15c197653ac3a1f39e8c5eaa56155f364e67d87d66647cff1355b960093af1.png +0 -0
- data/tools/staticdocs/assets/js/2bb7bf90.1772f030.js +1 -0
- data/tools/staticdocs/assets/js/411898ad.f7b3ff17.js +1 -0
- data/tools/staticdocs/assets/js/5b233ba7.9d6ba314.js +1 -0
- data/tools/staticdocs/assets/js/6831b732.1318b398.js +1 -0
- data/tools/staticdocs/assets/js/696b4199.1e950fcb.js +1 -0
- data/tools/staticdocs/assets/js/867640d5.27d9d599.js +1 -0
- data/tools/staticdocs/assets/js/89e76475.e1b0dbdb.js +1 -0
- data/tools/staticdocs/assets/js/964eb012.0e04c58d.js +1 -0
- data/tools/staticdocs/assets/js/9d6e81d0.36405219.js +1 -0
- data/tools/staticdocs/assets/js/a677c089.cfa50691.js +1 -0
- data/tools/staticdocs/assets/js/a9b2dc27.805dc1ba.js +1 -0
- data/tools/staticdocs/assets/js/aa6b6c1b.ef9b0f38.js +1 -0
- data/tools/staticdocs/assets/js/b062d239.57d6e194.js +1 -0
- data/tools/staticdocs/assets/js/b6d70f94.a9228642.js +1 -0
- data/tools/staticdocs/assets/js/c24eae19.0575c394.js +1 -0
- data/tools/staticdocs/assets/js/d1b923aa.da892cde.js +1 -0
- data/tools/staticdocs/assets/js/d66bf9c0.80a50660.js +1 -0
- data/tools/staticdocs/assets/js/d9b92eba.5db8667e.js +1 -0
- data/tools/staticdocs/assets/js/{main.8d947189.js → main.a8e2c06c.js} +5 -5
- data/tools/staticdocs/assets/js/{runtime~main.d38c5d36.js → runtime~main.7102cb65.js} +1 -1
- data/tools/staticdocs/docs/configuration/accessors.html +4 -3
- data/tools/staticdocs/docs/configuration/command.html +1 -1
- data/tools/staticdocs/docs/configuration/format.html +1 -1
- data/tools/staticdocs/docs/configuration/interfaces.html +15 -4
- data/tools/staticdocs/docs/configuration/plugins.html +5 -5
- data/tools/staticdocs/docs/configuration/protocols.html +7 -6
- data/tools/staticdocs/docs/configuration/ssl-tls.html +115 -76
- data/tools/staticdocs/docs/configuration/table.html +1 -1
- data/tools/staticdocs/docs/configuration/target.html +1 -1
- data/tools/staticdocs/docs/configuration/telemetry-screens.html +1 -1
- data/tools/staticdocs/docs/configuration/telemetry.html +1 -1
- data/tools/staticdocs/docs/configuration.html +1 -1
- data/tools/staticdocs/docs/development/curl.html +4 -4
- data/tools/staticdocs/docs/development/developing.html +2 -2
- data/tools/staticdocs/docs/development/json-api.html +1 -1
- data/tools/staticdocs/docs/development/log-structure.html +1 -1
- data/tools/staticdocs/docs/development/roadmap.html +1 -1
- data/tools/staticdocs/docs/development/streaming-api.html +1 -1
- data/tools/staticdocs/docs/development/testing.html +1 -1
- data/tools/staticdocs/docs/development.html +1 -1
- data/tools/staticdocs/docs/getting-started/cli.html +2 -2
- data/tools/staticdocs/docs/getting-started/generators.html +2 -2
- data/tools/staticdocs/docs/getting-started/gettingstarted.html +1 -1
- data/tools/staticdocs/docs/getting-started/installation.html +1 -1
- data/tools/staticdocs/docs/getting-started/key-concepts.html +8 -4
- data/tools/staticdocs/docs/getting-started/podman.html +1 -1
- data/tools/staticdocs/docs/getting-started/requirements.html +1 -1
- data/tools/staticdocs/docs/getting-started/upgrading.html +1 -1
- data/tools/staticdocs/docs/getting-started.html +1 -1
- data/tools/staticdocs/docs/guides/bridges.html +1 -1
- data/tools/staticdocs/docs/guides/cfs.html +12 -12
- data/tools/staticdocs/docs/guides/custom-widgets.html +1 -1
- data/tools/staticdocs/docs/guides/dynamic-packets.html +1 -1
- data/tools/staticdocs/docs/guides/exposing-microservices.html +4 -4
- data/tools/staticdocs/docs/guides/little-endian-bitfields.html +1 -1
- data/tools/staticdocs/docs/guides/local-mode.html +1 -1
- data/tools/staticdocs/docs/guides/logging.html +1 -1
- data/tools/staticdocs/docs/guides/monitoring.html +1 -1
- data/tools/staticdocs/docs/guides/performance.html +6 -6
- data/tools/staticdocs/docs/guides/raspberrypi.html +1 -1
- data/tools/staticdocs/docs/guides/script-writing.html +1 -1
- data/tools/staticdocs/docs/guides/scripting-api.html +55 -16
- data/tools/staticdocs/docs/guides.html +1 -1
- data/tools/staticdocs/docs/meta/contributing.html +1 -1
- data/tools/staticdocs/docs/meta/licenses.html +8 -8
- data/tools/staticdocs/docs/meta/philosophy.html +2 -2
- data/tools/staticdocs/docs/meta/xtce.html +1 -1
- data/tools/staticdocs/docs/meta.html +1 -1
- data/tools/staticdocs/docs/privacy.html +1 -1
- data/tools/staticdocs/docs/tools/admin.html +1 -1
- data/tools/staticdocs/docs/tools/autonomic.html +1 -1
- data/tools/staticdocs/docs/tools/bucket-explorer.html +2 -2
- data/tools/staticdocs/docs/tools/calendar.html +1 -1
- data/tools/staticdocs/docs/tools/cmd-sender.html +1 -1
- data/tools/staticdocs/docs/tools/cmd-tlm-server.html +1 -1
- data/tools/staticdocs/docs/tools/command_history.html +1 -1
- data/tools/staticdocs/docs/tools/data-extractor.html +1 -1
- data/tools/staticdocs/docs/tools/data-viewer.html +1 -1
- data/tools/staticdocs/docs/tools/handbooks.html +1 -1
- data/tools/staticdocs/docs/tools/limits-monitor.html +1 -1
- data/tools/staticdocs/docs/tools/packet-viewer.html +1 -1
- data/tools/staticdocs/docs/tools/script-runner.html +1 -1
- data/tools/staticdocs/docs/tools/table-manager.html +1 -1
- data/tools/staticdocs/docs/tools/tlm-grapher.html +1 -1
- data/tools/staticdocs/docs/tools/tlm-viewer.html +1 -1
- data/tools/staticdocs/docs/tools.html +1 -1
- data/tools/staticdocs/docs.html +1 -1
- data/tools/staticdocs/img/cosmos-containers.png +0 -0
- data/tools/staticdocs/img/cosmos-images.png +0 -0
- data/tools/staticdocs/index.html +1 -1
- data/tools/staticdocs/lunr-index-1746647301890.json +1 -0
- data/tools/staticdocs/lunr-index.json +1 -1
- data/tools/staticdocs/markdown-page.html +1 -1
- data/tools/staticdocs/search-doc-1746647301890.json +1 -0
- data/tools/staticdocs/search-doc.json +1 -1
- metadata +28 -24
- data/tools/staticdocs/assets/js/2bb7bf90.4a658ce6.js +0 -1
- data/tools/staticdocs/assets/js/411898ad.f7fc4d80.js +0 -1
- data/tools/staticdocs/assets/js/5b233ba7.2ea0179c.js +0 -1
- data/tools/staticdocs/assets/js/6831b732.0a867cbc.js +0 -1
- data/tools/staticdocs/assets/js/696b4199.2a7ff897.js +0 -1
- data/tools/staticdocs/assets/js/867640d5.2c0fa6d9.js +0 -1
- data/tools/staticdocs/assets/js/89e76475.a76d0072.js +0 -1
- data/tools/staticdocs/assets/js/964eb012.dbc2c206.js +0 -1
- data/tools/staticdocs/assets/js/9d6e81d0.44e2d544.js +0 -1
- data/tools/staticdocs/assets/js/a677c089.18f98b70.js +0 -1
- data/tools/staticdocs/assets/js/a9b2dc27.e01c9bb4.js +0 -1
- data/tools/staticdocs/assets/js/aa6b6c1b.3aad95fc.js +0 -1
- data/tools/staticdocs/assets/js/b062d239.535a2ceb.js +0 -1
- data/tools/staticdocs/assets/js/b6d70f94.7813125e.js +0 -1
- data/tools/staticdocs/assets/js/c24eae19.aaae7796.js +0 -1
- data/tools/staticdocs/assets/js/d1b923aa.a73e7e79.js +0 -1
- data/tools/staticdocs/assets/js/d66bf9c0.842d2efa.js +0 -1
- data/tools/staticdocs/assets/js/d9b92eba.34e63ba6.js +0 -1
- data/tools/staticdocs/lunr-index-1743825503427.json +0 -1
- data/tools/staticdocs/search-doc-1743825503427.json +0 -1
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openc3-cosmos-tool-docs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Melton
|
@@ -61,6 +61,8 @@ files:
|
|
61
61
|
- tools/staticdocs/assets/images/command_history-ecc9b618661ad0aefa0700047a8ab3b094372f2aa427e9fcd270dcd352a30408.png
|
62
62
|
- tools/staticdocs/assets/images/command_sender-83cf2e2343133c2883c405abd0b322f6d3d4a095c6ee800158a04c8eefe474ed.png
|
63
63
|
- tools/staticdocs/assets/images/connecting-0f804651a891ef6112a51ba8b2e4d8dcb46e3462dcbc94e7b3c75bff20fc04e7.png
|
64
|
+
- tools/staticdocs/assets/images/cosmos-containers-7ecd745840fcff307f0fec01ac4d88a8fa76d531abeae407fee0e508f50a487c.png
|
65
|
+
- tools/staticdocs/assets/images/cosmos-images-8e15c197653ac3a1f39e8c5eaa56155f364e67d87d66647cff1355b960093af1.png
|
64
66
|
- tools/staticdocs/assets/images/create_activity1-c05ffc03af2df852aeb3ad246f53f259af504e0e6c64cdac21f9126947c49f95.png
|
65
67
|
- tools/staticdocs/assets/images/create_activity2-58c7da6f79dd510701148c0c54fae02c830b9ca4af662a7b132987ed3410a8f7.png
|
66
68
|
- tools/staticdocs/assets/images/create_metadata1-a331ba8f0bd19bf5f8d7f2e083c3c7164e9b7b9936f5a7f83c4141c62a6c46f6.png
|
@@ -225,12 +227,12 @@ files:
|
|
225
227
|
- tools/staticdocs/assets/js/2047b354.d91f6c3e.js
|
226
228
|
- tools/staticdocs/assets/js/22b3ac48.0df9587b.js
|
227
229
|
- tools/staticdocs/assets/js/26b8abb2.7f8d4cb0.js
|
228
|
-
- tools/staticdocs/assets/js/2bb7bf90.
|
230
|
+
- tools/staticdocs/assets/js/2bb7bf90.1772f030.js
|
229
231
|
- tools/staticdocs/assets/js/35398c5c.fcf47881.js
|
230
232
|
- tools/staticdocs/assets/js/3969.afdd070b.js
|
231
233
|
- tools/staticdocs/assets/js/3dd7ef3b.c3455b97.js
|
232
234
|
- tools/staticdocs/assets/js/40365d27.5ed2e9b5.js
|
233
|
-
- tools/staticdocs/assets/js/411898ad.
|
235
|
+
- tools/staticdocs/assets/js/411898ad.f7b3ff17.js
|
234
236
|
- tools/staticdocs/assets/js/42170351.fbc05869.js
|
235
237
|
- tools/staticdocs/assets/js/43652efd.60fa883f.js
|
236
238
|
- tools/staticdocs/assets/js/5205.c6f31e57.js
|
@@ -238,7 +240,7 @@ files:
|
|
238
240
|
- tools/staticdocs/assets/js/53ca7c5b.fe331a71.js
|
239
241
|
- tools/staticdocs/assets/js/54d0d530.ef91ba12.js
|
240
242
|
- tools/staticdocs/assets/js/5761.e7fabbc9.js
|
241
|
-
- tools/staticdocs/assets/js/5b233ba7.
|
243
|
+
- tools/staticdocs/assets/js/5b233ba7.9d6ba314.js
|
242
244
|
- tools/staticdocs/assets/js/5bc719f6.6d27292c.js
|
243
245
|
- tools/staticdocs/assets/js/5c6ce5ec.652b922b.js
|
244
246
|
- tools/staticdocs/assets/js/5e3ed378.8b51f7c0.js
|
@@ -246,8 +248,8 @@ files:
|
|
246
248
|
- tools/staticdocs/assets/js/62df909c.dd5f3a0c.js
|
247
249
|
- tools/staticdocs/assets/js/630e5448.699a9dec.js
|
248
250
|
- tools/staticdocs/assets/js/651.a043d7b1.js
|
249
|
-
- tools/staticdocs/assets/js/6831b732.
|
250
|
-
- tools/staticdocs/assets/js/696b4199.
|
251
|
+
- tools/staticdocs/assets/js/6831b732.1318b398.js
|
252
|
+
- tools/staticdocs/assets/js/696b4199.1e950fcb.js
|
251
253
|
- tools/staticdocs/assets/js/6b210247.6a77064a.js
|
252
254
|
- tools/staticdocs/assets/js/6b65133b.0376a397.js
|
253
255
|
- tools/staticdocs/assets/js/6f92e431.6439052e.js
|
@@ -256,39 +258,39 @@ files:
|
|
256
258
|
- tools/staticdocs/assets/js/75e64983.324643a8.js
|
257
259
|
- tools/staticdocs/assets/js/7f5b2696.a3dc640e.js
|
258
260
|
- tools/staticdocs/assets/js/80c97f38.607160d3.js
|
259
|
-
- tools/staticdocs/assets/js/867640d5.
|
260
|
-
- tools/staticdocs/assets/js/89e76475.
|
261
|
+
- tools/staticdocs/assets/js/867640d5.27d9d599.js
|
262
|
+
- tools/staticdocs/assets/js/89e76475.e1b0dbdb.js
|
261
263
|
- tools/staticdocs/assets/js/8f7843ee.abe30983.js
|
262
264
|
- tools/staticdocs/assets/js/9357.9a7e89b5.js
|
263
265
|
- tools/staticdocs/assets/js/9424f0b3.3683501c.js
|
264
|
-
- tools/staticdocs/assets/js/964eb012.
|
266
|
+
- tools/staticdocs/assets/js/964eb012.0e04c58d.js
|
265
267
|
- tools/staticdocs/assets/js/97535711.e595488c.js
|
266
268
|
- tools/staticdocs/assets/js/99581c43.841b4a2e.js
|
267
|
-
- tools/staticdocs/assets/js/9d6e81d0.
|
269
|
+
- tools/staticdocs/assets/js/9d6e81d0.36405219.js
|
268
270
|
- tools/staticdocs/assets/js/9fb6059a.821f7504.js
|
269
|
-
- tools/staticdocs/assets/js/a677c089.
|
271
|
+
- tools/staticdocs/assets/js/a677c089.cfa50691.js
|
270
272
|
- tools/staticdocs/assets/js/a9987364.b418f772.js
|
271
|
-
- tools/staticdocs/assets/js/a9b2dc27.
|
272
|
-
- tools/staticdocs/assets/js/aa6b6c1b.
|
273
|
-
- tools/staticdocs/assets/js/b062d239.
|
273
|
+
- tools/staticdocs/assets/js/a9b2dc27.805dc1ba.js
|
274
|
+
- tools/staticdocs/assets/js/aa6b6c1b.ef9b0f38.js
|
275
|
+
- tools/staticdocs/assets/js/b062d239.57d6e194.js
|
274
276
|
- tools/staticdocs/assets/js/b4596165.c648533a.js
|
275
|
-
- tools/staticdocs/assets/js/b6d70f94.
|
277
|
+
- tools/staticdocs/assets/js/b6d70f94.a9228642.js
|
276
278
|
- tools/staticdocs/assets/js/b9f60ba6.4c0bb1dd.js
|
277
279
|
- tools/staticdocs/assets/js/bd0034eb.8ad39448.js
|
278
|
-
- tools/staticdocs/assets/js/c24eae19.
|
280
|
+
- tools/staticdocs/assets/js/c24eae19.0575c394.js
|
279
281
|
- tools/staticdocs/assets/js/c2598f55.812cdcd1.js
|
280
282
|
- tools/staticdocs/assets/js/c5388ca4.32f8f561.js
|
281
283
|
- tools/staticdocs/assets/js/cb8c3f08.07d1c9e9.js
|
282
284
|
- tools/staticdocs/assets/js/cd879be4.59af1749.js
|
283
285
|
- tools/staticdocs/assets/js/ce89ef36.6b89b0fe.js
|
284
|
-
- tools/staticdocs/assets/js/d1b923aa.
|
286
|
+
- tools/staticdocs/assets/js/d1b923aa.da892cde.js
|
285
287
|
- tools/staticdocs/assets/js/d1bfc316.a58b9bbd.js
|
286
288
|
- tools/staticdocs/assets/js/d24bf9b6.9fef8263.js
|
287
289
|
- tools/staticdocs/assets/js/d57a4b5d.c74b62b1.js
|
288
290
|
- tools/staticdocs/assets/js/d5d77c37.e812e6e7.js
|
289
|
-
- tools/staticdocs/assets/js/d66bf9c0.
|
291
|
+
- tools/staticdocs/assets/js/d66bf9c0.80a50660.js
|
290
292
|
- tools/staticdocs/assets/js/d8ca4191.8df86c99.js
|
291
|
-
- tools/staticdocs/assets/js/d9b92eba.
|
293
|
+
- tools/staticdocs/assets/js/d9b92eba.5db8667e.js
|
292
294
|
- tools/staticdocs/assets/js/db8fa1d0.f1eed806.js
|
293
295
|
- tools/staticdocs/assets/js/dbe31111.75e9fc53.js
|
294
296
|
- tools/staticdocs/assets/js/dc5f7beb.9e4e6681.js
|
@@ -296,8 +298,8 @@ files:
|
|
296
298
|
- tools/staticdocs/assets/js/e501b0d1.d3a1e4bc.js
|
297
299
|
- tools/staticdocs/assets/js/f15615f1.49804e96.js
|
298
300
|
- tools/staticdocs/assets/js/fd886806.124ffe26.js
|
299
|
-
- tools/staticdocs/assets/js/main.
|
300
|
-
- tools/staticdocs/assets/js/runtime~main.
|
301
|
+
- tools/staticdocs/assets/js/main.a8e2c06c.js
|
302
|
+
- tools/staticdocs/assets/js/runtime~main.7102cb65.js
|
301
303
|
- tools/staticdocs/docs.html
|
302
304
|
- tools/staticdocs/docs/configuration.html
|
303
305
|
- tools/staticdocs/docs/configuration/accessors.html
|
@@ -481,6 +483,8 @@ files:
|
|
481
483
|
- tools/staticdocs/img/command_sender/mode_menu.png
|
482
484
|
- tools/staticdocs/img/contact/jason.png
|
483
485
|
- tools/staticdocs/img/contact/ryan.jpeg
|
486
|
+
- tools/staticdocs/img/cosmos-containers.png
|
487
|
+
- tools/staticdocs/img/cosmos-images.png
|
484
488
|
- tools/staticdocs/img/data_extractor/add_item.png
|
485
489
|
- tools/staticdocs/img/data_extractor/add_packet.png
|
486
490
|
- tools/staticdocs/img/data_extractor/add_target.png
|
@@ -630,10 +634,10 @@ files:
|
|
630
634
|
- tools/staticdocs/img/telemetry_viewer/widgets/verticalbox.png
|
631
635
|
- tools/staticdocs/img/telemetry_viewer/widgets/width.png
|
632
636
|
- tools/staticdocs/index.html
|
633
|
-
- tools/staticdocs/lunr-index-
|
637
|
+
- tools/staticdocs/lunr-index-1746647301890.json
|
634
638
|
- tools/staticdocs/lunr-index.json
|
635
639
|
- tools/staticdocs/markdown-page.html
|
636
|
-
- tools/staticdocs/search-doc-
|
640
|
+
- tools/staticdocs/search-doc-1746647301890.json
|
637
641
|
- tools/staticdocs/search-doc.json
|
638
642
|
- tools/staticdocs/sitemap.xml
|
639
643
|
homepage: https://github.com/OpenC3/cosmos
|
@@ -655,7 +659,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
655
659
|
- !ruby/object:Gem::Version
|
656
660
|
version: '0'
|
657
661
|
requirements: []
|
658
|
-
rubygems_version: 3.6.
|
662
|
+
rubygems_version: 3.6.8
|
659
663
|
specification_version: 4
|
660
664
|
summary: OpenC3 COSMOS Documentation
|
661
665
|
test_files: []
|
@@ -1 +0,0 @@
|
|
1
|
-
"use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["7637"],{2695:function(e,t,n){n.r(t),n.d(t,{default:()=>h,frontMatter:()=>o,metadata:()=>s,assets:()=>l,toc:()=>c,contentTitle:()=>a});var s=JSON.parse('{"id":"getting-started/generators","title":"Code Generators","description":"Using openc3.sh to generate code","source":"@site/docs/getting-started/generators.md","sourceDirName":"getting-started","slug":"/getting-started/generators","permalink":"/tools/staticdocs/docs/getting-started/generators","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/getting-started/generators.md","tags":[],"version":"current","sidebarPosition":6,"frontMatter":{"sidebar_position":6,"title":"Code Generators","description":"Using openc3.sh to generate code","sidebar_custom_props":{"myEmoji":"\uD83C\uDFED"}},"sidebar":"defaultSidebar","previous":{"title":"Command Line Interface","permalink":"/tools/staticdocs/docs/getting-started/cli"},"next":{"title":"Podman","permalink":"/tools/staticdocs/docs/getting-started/podman"}}'),i=n("2322"),r=n("2840");let o={sidebar_position:6,title:"Code Generators",description:"Using openc3.sh to generate code",sidebar_custom_props:{myEmoji:"\uD83C\uDFED"}},a=void 0,l={},c=[{value:"Plugin Generator",id:"plugin-generator",level:2},{value:"Target Generator",id:"target-generator",level:2},{value:"Microservice Generator",id:"microservice-generator",level:2},{value:"Conversion Generator",id:"conversion-generator",level:2},{value:"Limits Response Generator",id:"limits-response-generator",level:2},{value:"Widget Generator",id:"widget-generator",level:2},{value:"Tool Generator",id:"tool-generator",level:2}];function d(e){let t={a:"a",admonition:"admonition",code:"code",h2:"h2",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(t.p,{children:["The COSMOS Code Generators are built into the scripts ",(0,i.jsx)(t.code,{children:"openc3.sh"})," and ",(0,i.jsx)(t.code,{children:"openc3.bat"})," that are included in the COSMOS ",(0,i.jsx)(t.a,{href:"https://github.com/OpenC3/cosmos-project",children:"project"})," (more about ",(0,i.jsx)(t.a,{href:"key-concepts#projects",children:"projects"}),")."]}),"\n",(0,i.jsxs)(t.p,{children:["If you followed the ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/getting-started/installation",children:"Installation Guide"})," you should already be inside a cloned ",(0,i.jsx)(t.a,{href:"https://github.com/OpenC3/cosmos-project",children:"openc3-project"})," which is in your PATH (necessary for openc3.bat / openc3.sh to be resolved). To see all the available code generators type the following:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"% openc3.sh cli generate\nUnknown generator ''. Valid generators: plugin, target, microservice, widget, conversion,\nlimits_response, tool, tool_vue, tool_angular, tool_react, tool_svelte\n"})}),"\n",(0,i.jsx)(t.admonition,{title:"Training Available",type:"note",children:(0,i.jsxs)(t.p,{children:["If any of this gets confusing, contact us at ",(0,i.jsx)("a",{href:"mailto:support@openc3.com",children:(0,i.jsx)(t.a,{href:"mailto:support@openc3.com",children:"support@openc3.com"})}),". We have training classes available!"]})}),"\n",(0,i.jsx)(t.h2,{id:"plugin-generator",children:"Plugin Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The plugin generator creates the scaffolding for a new COSMOS Plugin. It requires a plugin name and will create a new directory called ",(0,i.jsx)(t.code,{children:"openc3-cosmos-<name>"}),". For example:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"% openc3.sh cli generate plugin\nUsage: cli generate plugin <NAME>\n\n% openc3.sh cli generate plugin GSE\nPlugin openc3-cosmos-gse successfully generated!\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:".gitignore"}),(0,i.jsx)(t.td,{children:"Tells git to ignore any node_modules directory (for tool development)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"LICENSE.txt"}),(0,i.jsx)(t.td,{children:"License for the plugin. COSMOS Plugins should be licensed in a manner compatible with the AGPLv3, unless they are designed only for use with COSMOS Enterprise Edition."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"openc3-cosmos-gse.gemspec"}),(0,i.jsxs)(t.td,{children:["Gemspec file which should be edited to add user specific information like description, authors, emails, homepage, etc. The name of this file is used in compiling the plugin contents into the final corresponding gem file: e.g. openc3-cosmos-gse-1.0.0.gem. COSMOS plugins should always begin with the openc3-cosmos prefix to make them easily identifiable in the Rubygems repository. The file is formatted as documented at: ",(0,i.jsx)(t.a,{href:"https://guides.rubygems.org/specification-reference/",children:"https://guides.rubygems.org/specification-reference/"})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"plugin.txt"}),(0,i.jsxs)(t.td,{children:["COSMOS specific file for Plugin creation. Learn more ",(0,i.jsx)(t.a,{href:"../configuration/plugins",children:"here"}),"."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Rakefile"}),(0,i.jsx)(t.td,{children:'Ruby Rakefile configured to support building the plugin by running "openc3.sh cli rake build VERSION=X.X.X" where X.X.X is the plugin version number'})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"README.md"}),(0,i.jsx)(t.td,{children:"Markdown file used to document the plugin"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"requirements.txt"}),(0,i.jsx)(t.td,{children:"Python dependencies file (only for Python plugins)"})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"While this structure is required, it is not very useful by itself. The plugin generator just creates the framework for other generators to use."}),"\n",(0,i.jsx)(t.h2,{id:"target-generator",children:"Target Generator"}),"\n",(0,i.jsx)(t.p,{children:"The target generator creates the scaffolding for a new COSMOS Target. It must operate inside an existing COSMOS plugin and requires a target name. For example:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate target\nUsage: cli generate target <NAME> (--ruby or --python)\n\nopenc3-cosmos-gse % openc3.sh cli generate target GSE\nTarget GSE successfully generated!\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE"}),(0,i.jsx)(t.td,{children:"Contains the configuration for the GSE target. The target name is always defined in all caps. This is typically the default name of the target, but well-designed targets will allow themselves to be renamed at installation."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/cmd_tlm"}),(0,i.jsx)(t.td,{children:"Contains the command and telemetry definition files for the GSE target. These files capture the format of the commands that can be sent to the target, and the telemetry packets that are expected to be received by COSMOS from the target. Note that the files in this folder are processed in alphabetical order by default. That can matter if you reference a packet in another file (it must already have been defined)."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/cmd_tlm/cmd.txt"}),(0,i.jsxs)(t.td,{children:["Example ",(0,i.jsx)(t.a,{href:"../configuration/command",children:"command"})," configuration. Will need to be edited for the target specific commands."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/cmd_tlm/tlm.txt"}),(0,i.jsxs)(t.td,{children:["Example ",(0,i.jsx)(t.a,{href:"../configuration/telemetry",children:"telemetry"})," configuration. Will need to be edited for the target specific telemetry."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/lib"}),(0,i.jsxs)(t.td,{children:["Contains any custom code required by the target. Good examples of custom code are library files, custom ",(0,i.jsx)(t.a,{href:"../configuration/interfaces",children:"interface"})," classes and ",(0,i.jsx)(t.a,{href:"../configuration/protocols",children:"protocols"}),"."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/lib/gse.rb/py"}),(0,i.jsx)(t.td,{children:"Example library file which can be expanded as the target is developed. COSMOS recommends building up library methods to avoid code duplication and ease reuse."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/procedures"}),(0,i.jsxs)(t.td,{children:["This folder contains target specific procedures and helper methods which exercise functionality of the target. These procedures should be kept simple and only use the command and telemetry definitions associated with this target. See the ",(0,i.jsx)(t.a,{href:"../guides/script-writing#script-organization",children:"Scripting Guide"})," for more information."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/procedures/procedure.rb/py"}),(0,i.jsx)(t.td,{children:"Procedure with an example of sending a command and checking telemetry"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/public"}),(0,i.jsxs)(t.td,{children:["Put image files here for use in Telemetry Viewer Canvas Image widgets such as ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/telemetry-screens#canvasimage",children:"CANVASIMAGE"})," and ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/telemetry-screens#canvasimagevalue",children:"CANVASIMAGEVALUE"})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/screens"}),(0,i.jsxs)(t.td,{children:["Contains telemetry ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/telemetry-screens",children:"screens"})," for the target"]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/screens/status.txt"}),(0,i.jsxs)(t.td,{children:["Example ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/telemetry-screens",children:"screen"})," to display telemetry values"]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/target.txt"}),(0,i.jsxs)(t.td,{children:[(0,i.jsx)(t.a,{href:"../configuration/target",children:"Target"})," configuration such as ignoring command and telemetry items and how to process the cmd/tlm files"]})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"It also updates the plugin.txt file to add the new target:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:"VARIABLE gse_target_name GSE\n\nTARGET GSE <%= gse_target_name %>\nINTERFACE <%= gse_target_name %>_INT tcpip_client_interface.rb host.docker.internal 8080 8081 10.0 nil BURST\n MAP_TARGET <%= gse_target_name %>\n"})}),"\n",(0,i.jsx)(t.h2,{id:"microservice-generator",children:"Microservice Generator"}),"\n",(0,i.jsx)(t.p,{children:"The microservice generator creates the scaffolding for a new COSMOS Microservice. It must operate inside an existing COSMOS plugin and requires a target name. For example:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate microservice\nUsage: cli generate microservice <NAME> (--ruby or --python)\n\nopenc3-cosmos-gse % openc3.sh cli generate microservice background\nMicroservice BACKGROUND successfully generated!\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"microservices/BACKGROUND"}),(0,i.jsx)(t.td,{children:"Contains the code and any necessary configuration for the BACKGROUND microservice. The name is always defined in all caps. This is typically the default name of the microservice, but well-designed microservices will allow themselves to be renamed at installation."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"microservices/BACKGROUND/background.rb"}),(0,i.jsx)(t.td,{children:"Fully functional microservice which will run every minute and log a message. Edit to implement any custom logic that you want to run in the background. Potential uses are safety microservices which can check and autonomously respond to complex events and take action (NOTE: Simple actions might just require a Limits Response)."})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"It also updates the plugin.txt file to add the new microservice:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:"MICROSERVICE BACKGROUND background-microservice\n CMD ruby background.rb\n"})}),"\n",(0,i.jsx)(t.h2,{id:"conversion-generator",children:"Conversion Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The conversion generator creates the scaffolding for a new COSMOS ",(0,i.jsx)(t.a,{href:"../configuration/telemetry#read_conversion",children:"Conversion"}),". It must operate inside an existing COSMOS plugin and requires both a target name and conversion name. For example:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate conversion\nUsage: cli generate conversion <TARGET> <NAME> (--ruby or --python)\n\nopenc3-cosmos-gse % openc3.sh cli generate limits_response GSE double\nConversion targets/GSE/lib/double_conversion.rb successfully generated!\nTo use the conversion add the following to a telemetry item:\n READ_CONVERSION double_conversion.rb\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsx)(t.tbody,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/lib/double_conversion.rb"}),(0,i.jsx)(t.td,{children:"Fully functional Conversion which has an example implementation of the call() method to convert any existing COSMOS values."})]})})]}),"\n",(0,i.jsx)(t.p,{children:"As the generator states, to use this conversion code you must add it to a telemetry item. For example:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:'TELEMETRY GSE STATUS BIG_ENDIAN "Telemetry description"\n # Keyword Name BitSize Type ID Description\n APPEND_ID_ITEM ID 16 INT 1 "Identifier"\n APPEND_ITEM VALUE 32 FLOAT "Value"\n READ_CONVERSION double_conversion.rb\n APPEND_ITEM BOOL 8 UINT "Boolean"\n STATE FALSE 0\n STATE TRUE 1\n APPEND_ITEM LABEL 0 STRING "The label to apply"\n'})}),"\n",(0,i.jsx)(t.h2,{id:"limits-response-generator",children:"Limits Response Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The limits_response generator creates the scaffolding for a new COSMOS ",(0,i.jsx)(t.a,{href:"../configuration/telemetry#limits_response",children:"Limits Response"}),". It must operate inside an existing COSMOS plugin and requires both a target name and limits response name. For example:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate limits_response\nUsage: cli generate limits_response <TARGET> <NAME> (--ruby or --python)\n\nopenc3-cosmos-gse % openc3.sh cli generate limits_response GSE safe\nLimits response targets/GSE/lib/safe_limits_response.rb successfully generated!\nTo use the limits response add the following to a telemetry item:\n LIMITS_RESPONSE safe_limits_response.rb\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsx)(t.tbody,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/lib/safe_limits_response.rb"}),(0,i.jsx)(t.td,{children:"Fully functional Limits Response which has an example implementation of the call() method and taking action based on the current limits state of the particular item"})]})})]}),"\n",(0,i.jsx)(t.p,{children:"As the generator states, to use this limits code you must add it to a telemetry item which has limits defined. In the generated GSE target, none of the items have limits defined so you first need to add limits and then add the response."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:'TELEMETRY GSE STATUS BIG_ENDIAN "Telemetry description"\n # Keyword Name BitSize Type ID Description\n APPEND_ID_ITEM ID 16 INT 1 "Identifier"\n APPEND_ITEM VALUE 32 FLOAT "Value"\n LIMITS DEFAULT 1 ENABLED -80.0 -70.0 60.0 80.0 -20.0 20.0\n LIMITS_RESPONSE safe_limits_response.rb\n APPEND_ITEM BOOL 8 UINT "Boolean"\n STATE FALSE 0\n STATE TRUE 1\n APPEND_ITEM LABEL 0 STRING "The label to apply"\n'})}),"\n",(0,i.jsx)(t.h2,{id:"widget-generator",children:"Widget Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The conversion generator creates the scaffolding for a new COSMOS Widget for use in ",(0,i.jsx)(t.a,{href:"../configuration/telemetry-screens",children:"Telemetry Viewer Screens"}),". For more information see the ",(0,i.jsx)(t.a,{href:"../guides/custom-widgets",children:"Custom Widget"})," guide. It must operate inside an existing COSMOS plugin and requires a widget name. For example:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate widget\nUsage: cli generate widget <SuperdataWidget>\n\nopenc3-cosmos-gse % openc3.sh cli generate widget HelloworldWidget\nWidget HelloworldWidget successfully generated!\nPlease be sure HelloworldWidget does not overlap an existing widget: https://docs.openc3.com/docs/configuration/telemetry-screens\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsx)(t.tbody,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/HelloworldWidget.vue"}),(0,i.jsx)(t.td,{children:"Fully functional widget which displays a simple value. This can be expanded using existing COSMOS Vue.js code to create any data visualization imaginable."})]})})]}),"\n",(0,i.jsx)(t.p,{children:"It also updates the plugin.txt file to add the new widget:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:"WIDGET Helloworld\n"})}),"\n",(0,i.jsx)(t.h2,{id:"tool-generator",children:"Tool Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The tool generator creates the scaffolding for a new COSMOS Tool. It's It must operate inside an existing COSMOS plugin and requires a tool name. Developing a custom tool requires intensive knowledge of a Javascript framework such as Vue.js, Angular, React, or Svelte. Since all the COSMOS tools are built in Vue.js, that is the recommended framework for new tool development. For additional help on frontend development, see ",(0,i.jsx)(t.a,{href:"../development/developing#running-a-frontend-application",children:"Running a Frontend Application"}),"."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate tool\nUsage: cli generate tool 'Tool Name'\n\nopenc3-cosmos-gse % openc3.sh cli generate widget DataVis\nTool datavis successfully generated!\nPlease be sure datavis does not conflict with any other tools\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/App.vue"}),(0,i.jsx)(t.td,{children:"Basic Vue template to render the application."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/main.js"}),(0,i.jsx)(t.td,{children:"Entry point for the new tool which loads Vue, Vuetify, and other libraries."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/router.js"}),(0,i.jsx)(t.td,{children:"Vue component router."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/tools/datavis"}),(0,i.jsx)(t.td,{children:"Contains all the files necessary to serve a web-based tool named datavis. The name is always defined in all lowercase. Due to technical limitations, the toolname must be unique and cannot be renamed at installation."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/tools/datavis/datavis.vue"}),(0,i.jsx)(t.td,{children:"Fully functional tool which displays a simple button. This can be expanded using existing COSMOS Vue.js code to create any tool imaginable."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"package.json"}),(0,i.jsx)(t.td,{children:"Build and dependency definition file. Used by npm or yarn to build the tool."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"vue.config.js"}),(0,i.jsx)(t.td,{children:"Vue configuration file used to serve the application in development and build the application."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"<dotfiles>"}),(0,i.jsx)(t.td,{children:"Various dotfiles which help configure formatters and tools for Javascript frontend development"})]})]})]}),"\n",(0,i.jsxs)(t.p,{children:["It also updates the plugin.txt file to add the new tool. The icon can be changed to any of the material design icons found ",(0,i.jsx)(t.a,{href:"https://pictogrammers.com/library/mdi/",children:"here"}),"."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:'TOOL datavis "DataVis"\n INLINE_URL main.js\n ICON mdi-file-cad-box\n'})})]})}function h(e={}){let{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},2840:function(e,t,n){n.d(t,{Z:function(){return a},a:function(){return o}});var s=n(2784);let i={},r=s.createContext(i);function o(e){let t=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]);
|
@@ -1 +0,0 @@
|
|
1
|
-
"use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["602"],{8747:function(e,n,i){i.r(n),i.d(n,{default:()=>d,frontMatter:()=>r,metadata:()=>t,assets:()=>l,toc:()=>a,contentTitle:()=>c});var t=JSON.parse('{"id":"development/curl","title":"Testing with Curl","description":"How to use Curl to hit the COSMOS APIs","source":"@site/docs/development/curl.md","sourceDirName":"development","slug":"/development/curl","permalink":"/tools/staticdocs/docs/development/curl","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/development/curl.md","tags":[],"version":"current","frontMatter":{"title":"Testing with Curl","description":"How to use Curl to hit the COSMOS APIs","sidebar_custom_props":{"myEmoji":"\uD83C\uDF0A"}},"sidebar":"defaultSidebar","previous":{"title":"Development","permalink":"/tools/staticdocs/docs/development"},"next":{"title":"Developing COSMOS","permalink":"/tools/staticdocs/docs/development/developing"}}'),s=i("2322"),o=i("2840");let r={title:"Testing with Curl",description:"How to use Curl to hit the COSMOS APIs",sidebar_custom_props:{myEmoji:"\uD83C\uDF0A"}},c=void 0,l={},a=[{value:"Curl Example with OpenC3 COSMOS Open Source",id:"curl-example-with-openc3-cosmos-open-source",level:2},{value:"Curl Example with OpenC3 COSMOS Enterprise",id:"curl-example-with-openc3-cosmos-enterprise",level:2},{value:"Suite Runner Example",id:"suite-runner-example",level:2}];function p(e){let n={admonition:"admonition",code:"code",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.admonition,{title:"This documentation is for COSMOS Developers",type:"note",children:(0,s.jsx)(n.p,{children:"This information is just generally used behind the scenes in COSMOS tools"})}),"\n",(0,s.jsx)(n.p,{children:"The COSMOS APIs are all served over HTTP, which means you can use curl to experiment with them. Curl is a great tool for seeing exactly how the API responds to any given request."}),"\n",(0,s.jsx)(n.h2,{id:"curl-example-with-openc3-cosmos-open-source",children:"Curl Example with OpenC3 COSMOS Open Source"}),"\n",(0,s.jsx)(n.p,{children:"OpenC3 COSMOS Open Source just has a single user account, so all you need to do is pass the single password as the token with your requests like this."}),"\n",(0,s.jsx)(n.p,{children:"Request:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'curl -i -H "Content-Type: application/json-rpc" -H "Authorization: password" -d \'{"jsonrpc": "2.0", "method": "tlm", "params": ["INST HEALTH_STATUS TEMP1"], "keyword_params": {"scope": "DEFAULT"}, "id": 8}\' -X POST http://127.0.0.1:2900/openc3-api/api\n'})}),"\n",(0,s.jsx)(n.p,{children:"Response:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'HTTP/1.1 200 OK\nCache-Control: max-age=0, private, must-revalidate\nContent-Length: 51\nContent-Type: application/json-rpc\nEtag: W/"e806aacfdbed0b325e7a5928e3bb5cf4"\nVary: Origin\nX-Request-Id: bbad6c6b-6d22-4374-a86f-b5b0b95e6939\nX-Runtime: 0.059044\nDate: Sat, 04 Nov 2023 21:34:47 GMT\n\n{"jsonrpc":"2.0","id":8,"result":53.26555000000001}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"curl-example-with-openc3-cosmos-enterprise",children:"Curl Example with OpenC3 COSMOS Enterprise"}),"\n",(0,s.jsx)(n.p,{children:"OpenC3 COSMOS Enterprise uses the Keycloak Single Sign-on system, so you must first request a token from Keycloak using a username and password pair, before you make requests. By default this token will expire in 5 minutes, and will need to be refreshed if it expires before your next request."}),"\n",(0,s.jsx)(n.p,{children:"Keycloak Request:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# Get tokens from Keycloak - You will need to update the username and password with your account\ncurl -i -H \"Content-Type: application/x-www-form-urlencoded\" -d 'username=operator&password=operator&client_id=api&grant_type=password&scope=openid' -X POST http://127.0.0.1:2900/auth/realms/openc3/protocol/openid-connect/token\n"})}),"\n",(0,s.jsx)(n.p,{children:"Keycloak Response:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'HTTP/1.1 200 OK\nCache-Control: no-store\nContent-Length: 3207\nContent-Type: application/json\nPragma: no-cache\nReferrer-Policy: no-referrer\nSet-Cookie: KEYCLOAK_LOCALE=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; Path=/auth/realms/openc3/; HttpOnly\nSet-Cookie: KC_RESTART=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; Path=/auth/realms/openc3/; HttpOnly\nStrict-Transport-Security: max-age=31536000; includeSubDomains\nX-Content-Type-Options: nosniff\nX-Frame-Options: SAMEORIGIN\nX-Xss-Protection: 1; mode=block\nDate: Wed, 10 May 2023 00:40:40 GMT\n\n{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0cDlERmpNZGFXMy16WXptdlBqVTZnNTVqMVNhWGhkZHJqU0szQVNvaDhVIn0.eyJleHAiOjE2ODM2Nzk1NDAsImlhdCI6MTY4MzY3OTI0MCwianRpIjoiZmVlOTQwYWYtZDY3Ny00MWUyLWIzNWYtZDI5ODhiM2RhZGQ2IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDoyOTAwL2F1dGgvcmVhbG1zL29wZW5jMyIsInN1YiI6ImFjZTFlNmExLTkzMTktNDc2ZS1iZjQzLTZmM2NhYjllZTJkZSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFwaSIsInNlc3Npb25fc3RhdGUiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkiLCJhY3IiOiIxIiwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImRlZmF1bHQtcm9sZXMtb3BlbmMzIiwiQUxMU0NPUEVTX19vcGVyYXRvciIsIm9mZmxpbmVfYWNjZXNzIiwiQUxMU0NPUEVTX192aWV3ZXIiXX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJUaGUgT3BlcmF0b3IiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJvcGVyYXRvciIsImdpdmVuX25hbWUiOiJUaGUiLCJmYW1pbHlfbmFtZSI6Ik9wZXJhdG9yIn0.eSqSeZrmCTahwltz5jsu5r3w6W15T5h0BvIdqKWQBDcnxAcxKuT-Nwziw_ewySSgHeC172CIWJUpHVp8ACDQG-dfW4KkvA6AcGfSF_f8TBH_rZrVQwlvwwzdA_egGKzhZWcnAC8TDjXRxuaWmnOgWT0aaHZAoW8EvwmKp-1IVz2l0B-hqzfC7dkjMrCI1udLfDvDBza9OtuR-FnKGt8h4nYnRzr8pO2jwebPFyZlR00gVsyK-b411XqprpT-qpRObYZwH5womA-8xIiwRZj9dsfQ1TaHGFkp1LNzxcj_r6pfwVO263bohbeU7ImezQdbvGLJ9NHaglzVNroTui4BXA","expires_in":300,"refresh_expires_in":1800,"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI5NjNlMjJiMS0wZmYwLTRmZjktYTg0Zi1hOGI4MzcxOWFiMDEifQ.eyJleHAiOjE2ODM2ODEwNDAsImlhdCI6MTY4MzY3OTI0MCwianRpIjoiMmQyYjIyNmItNjJkOS00YjRjLWI3YTYtMGEwYjk4MGQyMjMwIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDoyOTAwL2F1dGgvcmVhbG1zL29wZW5jMyIsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6MjkwMC9hdXRoL3JlYWxtcy9vcGVuYzMiLCJzdWIiOiJhY2UxZTZhMS05MzE5LTQ3NmUtYmY0My02ZjNjYWI5ZWUyZGUiLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoiYXBpIiwic2Vzc2lvbl9zdGF0ZSI6ImYzNzg1OTY3LTJhNDYtNGMxMi1hZDBjLWNmZjdmYzQ3N2RmOSIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkifQ.1HlKdxQkaL5tYuHTXsOceLZFmNNLl9BjoA4oUl70x9M","token_type":"Bearer","id_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0cDlERmpNZGFXMy16WXptdlBqVTZnNTVqMVNhWGhkZHJqU0szQVNvaDhVIn0.eyJleHAiOjE2ODM2Nzk1NDAsImlhdCI6MTY4MzY3OTI0MCwiYXV0aF90aW1lIjowLCJqdGkiOiJhNDJkOTY1ZS1lMzU0LTRiM2QtOTIyYS1hOWE0ZDgwZWYxMTkiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjI5MDAvYXV0aC9yZWFsbXMvb3BlbmMzIiwiYXVkIjoiYXBpIiwic3ViIjoiYWNlMWU2YTEtOTMxOS00NzZlLWJmNDMtNmYzY2FiOWVlMmRlIiwidHlwIjoiSUQiLCJhenAiOiJhcGkiLCJzZXNzaW9uX3N0YXRlIjoiZjM3ODU5NjctMmE0Ni00YzEyLWFkMGMtY2ZmN2ZjNDc3ZGY5IiwiYXRfaGFzaCI6IjNBWE9ISkFKYzFPVldLd2Y0a0Q4TkEiLCJhY3IiOiIxIiwic2lkIjoiZjM3ODU5NjctMmE0Ni00YzEyLWFkMGMtY2ZmN2ZjNDc3ZGY5IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiVGhlIE9wZXJhdG9yIiwicHJlZmVycmVkX3VzZXJuYW1lIjoib3BlcmF0b3IiLCJnaXZlbl9uYW1lIjoiVGhlIiwiZmFtaWx5X25hbWUiOiJPcGVyYXRvciJ9.gdLl6KOKIIAdl6jYEuAXQrGCNvuwLQb3RDnwrHJdqyFXshiwofBiLMFreRsIE-33xXWNBU6pnSLQHPVlQU5Vmzlk0IOfk-b4yNq0dNa1TV1kmnxRl8w1ulTQYVZjdsN-oyLNwe0v3aJcYtbvIA3DP8rgO6bVv0ogkjWtlda6MbkyZN-har8x3raUVSlUPRP2Basy1xSMNNA1jvB-nEM-aubrUZE6r0PjI6PE1hbLPmuPbcX3uuIwXu2-UoXepkB8H7omUuMm-S98aHpRarwszC0mmHD5b_wiXusMVw4xYw8eavFue4zfw-T2IKuTVtxbMTygXIah6iqi4gkpL8Mx1w","not-before-policy":0,"session_state":"f3785967-2a46-4c12-ad0c-cff7fc477df9","scope":"openid profile email"}\n'})}),"\n",(0,s.jsx)(n.p,{children:"COSMOS Request:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'# COSMOS Request now looks like this:\n\ncurl -i -H "Content-Type: application/json-rpc" -H "Authorization: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0cDlERmpNZGFXMy16WXptdlBqVTZnNTVqMVNhWGhkZHJqU0szQVNvaDhVIn0.eyJleHAiOjE2ODM2Nzk1NDAsImlhdCI6MTY4MzY3OTI0MCwianRpIjoiZmVlOTQwYWYtZDY3Ny00MWUyLWIzNWYtZDI5ODhiM2RhZGQ2IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDoyOTAwL2F1dGgvcmVhbG1zL29wZW5jMyIsInN1YiI6ImFjZTFlNmExLTkzMTktNDc2ZS1iZjQzLTZmM2NhYjllZTJkZSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFwaSIsInNlc3Npb25fc3RhdGUiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkiLCJhY3IiOiIxIiwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImRlZmF1bHQtcm9sZXMtb3BlbmMzIiwiQUxMU0NPUEVTX19vcGVyYXRvciIsIm9mZmxpbmVfYWNjZXNzIiwiQUxMU0NPUEVTX192aWV3ZXIiXX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJUaGUgT3BlcmF0b3IiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJvcGVyYXRvciIsImdpdmVuX25hbWUiOiJUaGUiLCJmYW1pbHlfbmFtZSI6Ik9wZXJhdG9yIn0.eSqSeZrmCTahwltz5jsu5r3w6W15T5h0BvIdqKWQBDcnxAcxKuT-Nwziw_ewySSgHeC172CIWJUpHVp8ACDQG-dfW4KkvA6AcGfSF_f8TBH_rZrVQwlvwwzdA_egGKzhZWcnAC8TDjXRxuaWmnOgWT0aaHZAoW8EvwmKp-1IVz2l0B-hqzfC7dkjMrCI1udLfDvDBza9OtuR-FnKGt8h4nYnRzr8pO2jwebPFyZlR00gVsyK-b411XqprpT-qpRObYZwH5womA-8xIiwRZj9dsfQ1TaHGFkp1LNzxcj_r6pfwVO263bohbeU7ImezQdbvGLJ9NHaglzVNroTui4BXA" -d \'{"jsonrpc": "2.0", "method": "tlm", "params": ["INST HEALTH_STATUS TEMP1"], "keyword_params": {"scope": "DEFAULT"}, "id": 8}\' -X POST http://127.0.0.1:2900/openc3-api/api\n'})}),"\n",(0,s.jsx)(n.p,{children:"COSMOS Response:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'HTTP/1.1 200 OK\nCache-Control: max-age=0, private, must-revalidate\nContent-Type: application/json-rpc\nEtag: W/"1e44c0878528687014e1e60a1cbebdae"\nVary: Origin\nX-Request-Id: 47a8dd26-1348-4693-8df1-5375f60abc6c\nX-Runtime: 0.046477\nDate: Wed, 10 May 2023 00:41:33 GMT\nTransfer-Encoding: chunked\n\n{"jsonrpc":"2.0","id":8,"result":29.204100000000007}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"suite-runner-example",children:"Suite Runner Example"}),"\n",(0,s.jsxs)(n.p,{children:["It can be very useful to run the a suite or script remotely from a continuous testing server. COSMOS' REST API allows for this. To figure out what is required to run a certain task on the web GUI you can open up your browser's developer tools to monitor the network traffic. You will see all the requests and responses required to run a command and you can reformat them yourself to suit your own purposes. Below is an example of running a test script from a Chromium-based browser:\n",(0,s.jsx)(n.img,{src:"https://github.com/OpenC3/cosmos/assets/55999897/df642d42-43e0-47f9-9b52-d42746d9746b",alt:"Network Traffic in browser developer tools"})]}),"\n",(0,s.jsxs)(n.p,{children:['You can see that there are 5 transactions total. To investigate just right-click on the network transaction and click "copy as ',(0,s.jsx)(n.code,{children:"curl"}),'" (depends on the browser). Here is an example of the second one:']}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl 'http://localhost:2900/script-api/scripts/TARGET/procedures/cmd_tlm_test.rb/lock?scope=DEFAULT' \\\n -X 'POST' \\\n -H 'Accept: application/json' \\\n -H 'Accept-Language: en-US,en;q=0.9' \\\n -H 'Authorization: pass' \\\n -H 'Connection: keep-alive' \\\n -H 'Content-Length: 0' \\\n -H 'Origin: http://ascportal:2900' \\\n -H 'Referer: http://localhost:2900/tools/scriptrunner/?file=TARGET%2Fprocedures%2Fcmd_tlm_test.rb' \\\n -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0' \\\n --insecure\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Many of the browser-specific headers are not required. The important thing to notice here is the URL and the request (in this case ",(0,s.jsx)(n.code,{children:"POST"}),"). If we inspect all of these we'll find out what each one does:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Set the script contents","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"this updates any local changes)"}),"\n",(0,s.jsxs)(n.li,{children:["Note that this is a different request to ",(0,s.jsx)(n.code,{children:"GET"})," the script contents. This is done on the page load."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:"Lock the script (so other users can't edit it during execution)"}),"\n",(0,s.jsx)(n.li,{children:"Run script (this takes a JSON with options)"}),"\n",(0,s.jsx)(n.li,{children:"Open Websocket for logs"}),"\n",(0,s.jsx)(n.li,{children:"Request Result (this URL is a little different because the results are saved in redis)"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Below is a bash script which does all the above given some options. It requires ",(0,s.jsx)(n.code,{children:"curl"})," for the web requests and ",(0,s.jsx)(n.code,{children:"jq"})," for JSON parsing and formatting. It locks and runs the script, continually checks its status, then requests the result."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'#!/bin/bash\nset -e\nTARGET=${1:-\'TARGET\'}\nSCRIPT=${2:-\'procedures/cmd_tlm_test.rb\'}\nSUITE=${3:-\'TestSuite\'}\nCOSMOS_HOST=\'http://localhost:2900\'\nSCRIPT_API="$COSMOS_HOST/script-api"\nSCRIPT_PATH="scripts/$TARGET/$SCRIPT"\nCURL_ARGS=(\n -H \'Accept: application/json\'\n -H \'Authorization: password\'\n -H \'Accept-Language: en-US,en;q=0.9\'\n -H \'Connection: keep-alive\'\n -H \'Content-Type: application/json\'\n --insecure\n --silent )\n\n# Lock script #\ncurl "$SCRIPT_API/$SCRIPT_PATH/lock?scope=DEFAULT" -X "POST" "${CURL_ARGS[@]}"\n\n# Run script #\nRUN_OPTS=$(cat <<-json\n{\n "environment": [],\n "suiteRunner": {\n "method": "start",\n "suite": "$SUITE",\n "options": [\n "continueAfterError"\n ]\n }\n}\njson\n)\nRUN_OPTS=$(<<<"$RUN_OPTS" jq -rc .)\nID=$(curl "$SCRIPT_API/$SCRIPT_PATH/run?scope=DEFAULT" --data-raw "$RUN_OPTS" "${CURL_ARGS[@]}")\n\necho "Starting Script \'$SCRIPT_PATH\' at $(date) (may take up to 15 minutes)" > /dev/stderr\necho "You can monitor it in Script Runner here: $COSMOS_HOST/tools/scriptrunner/$ID" > /dev/stderr\n# Loop while Script ID is still running #\nwhile true; do\n SCRIPT_STATUS="$(curl "$SCRIPT_API/running-script?scope=DEFAULT" "${CURL_ARGS[@]}" | jq ".[]|select(.id==$ID)")"\n if [[ -z $SCRIPT_STATUS ]]; then\n break;\n fi\n sleep 2\ndone\n\n# Request results #\nBUCKET_FILE_URI="$(curl "$SCRIPT_API/completed-scripts?scope=DEFAULT" "${CURL_ARGS[@]}" |\\\n jq \'[.[]|select(.name | test("\'"${SCRIPT_PATH#scripts/}"\' "))][0] | .log | @uri\' -r)"\n\nURL="$(curl "$COSMOS_HOST/openc3-api/storage/download/$BUCKET_FILE_URI?bucket=OPENC3_LOGS_BUCKET&scope=DEFAULT" "${CURL_ARGS[@]}" |jq .url -r)"\n\ncurl "$COSMOS_HOST$URL" "${CURL_ARGS[@]}"\n'})})]})}function d(e={}){let{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},2840:function(e,n,i){i.d(n,{Z:function(){return c},a:function(){return r}});var t=i(2784);let s={},o=t.createContext(s);function r(e){let n=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]);
|
@@ -1 +0,0 @@
|
|
1
|
-
"use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["3522"],{5865:function(e,n,s){s.r(n),s.d(n,{default:()=>d,frontMatter:()=>l,metadata:()=>i,assets:()=>a,toc:()=>c,contentTitle:()=>r});var i=JSON.parse('{"id":"meta/licenses","title":"Licenses","description":"COSMOS licenses including the AGPLv3 vs Commercial","source":"@site/docs/meta/licenses.md","sourceDirName":"meta","slug":"/meta/licenses","permalink":"/tools/staticdocs/docs/meta/licenses","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/meta/licenses.md","tags":[],"version":"current","frontMatter":{"title":"Licenses","description":"COSMOS licenses including the AGPLv3 vs Commercial","sidebar_custom_props":{"myEmoji":"\uD83D\uDD75\uFE0F"}},"sidebar":"defaultSidebar","previous":{"title":"Contributing","permalink":"/tools/staticdocs/docs/meta/contributing"},"next":{"title":"Philosophy","permalink":"/tools/staticdocs/docs/meta/philosophy"}}'),o=s("2322"),t=s("2840");let l={title:"Licenses",description:"COSMOS licenses including the AGPLv3 vs Commercial",sidebar_custom_props:{myEmoji:"\uD83D\uDD75\uFE0F"}},r=void 0,a={},c=[{value:"AGPLv3",id:"agplv3",level:2},{value:"Evaluation and Education Use Only",id:"evaluation-and-education-use-only",level:2},{value:"Commercial License",id:"commercial-license",level:2},{value:"Why you should buy a Commercial License",id:"why-you-should-buy-a-commercial-license",level:3},{value:"FAQs",id:"faqs",level:2}];function h(e){let n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.p,{children:"OpenC3 COSMOS is offered under a tri-licensing model allowing users to choose between the following three options:"}),"\n",(0,o.jsx)(n.h2,{id:"agplv3",children:"AGPLv3"}),"\n",(0,o.jsxs)(n.p,{children:["This is our default open source license and the license that most free users use. The AGPLv3 is a modification of the GPLv3 which is what is known as a copy-left license or a viral license. You can read the whole thing here: ",(0,o.jsx)(n.a,{href:"https://github.com/OpenC3/cosmos/blob/main/LICENSE.txt",children:"OpenC3 AGPLv3"})]}),"\n",(0,o.jsx)(n.p,{children:"Obviously, the actual license text applies, but here is a short summary:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"The AGPL allows users to use the code however they want: For business, personal, etc., as long as they follow the other terms:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Users are anyone who could access the web-app. On the public internet, that is the whole world. On a private network, it is anyone with access to that network."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"The software is provided as-is, no warranty"}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Users must be given access to all the source code and are also allowed to use it however they want under the same terms of the AGPLv3. This includes any modifications made, anything added, and all plugins."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"For web applications (like COSMOS), a link must be provided to all of the source code."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"There are some key implications of the above:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"You cannot keep anything proprietary from your users. They have the rights to take the code (and configuration) and do anything they want with it. You CANNOT impede these rights or you are violating the AGPLv3 and YOU lose the rights to use our software."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"You must provide a digital link to all source code for your users, including plugins."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"All plugins must be licensed in an AGPLv3 compatible fashion. We recommend the MIT license because that allows your plugins to be compatible with the AGPLv3 and our commercial license. You can also use a dual license similar to what we do indicating the AGPLv3 or a purchased OpenC3 Commercial license."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"The AGPLv3 license is often chosen because it works well for open core products like COSMOS. Competitors cannot take the open source product and license it under different terms. They would be forever locked into the AGPLv3 which is difficult to monetize, because your customers can take any code you provide and publish it on the internet for free use by everyone."}),"\n",(0,o.jsx)(n.p,{children:"As the copyright holder, OpenC3 is able to license the product and derivatives commercially. No-one else can do this. (OpenC3 is also able to license legacy Ball Aerospace COSMOS code under IP agreement)"}),"\n",(0,o.jsx)(n.h2,{id:"evaluation-and-education-use-only",children:"Evaluation and Education Use Only"}),"\n",(0,o.jsxs)(n.p,{children:["This license takes effect as soon as you use any plugin we publish under Evaluation and Education terms. Currently the only plugin we use for this is our CCSDS CFDP plugin: ",(0,o.jsx)(n.a,{href:"https://github.com/OpenC3/openc3-cosmos-cfdp",children:"CFDP Plugin"})]}),"\n",(0,o.jsx)(n.p,{children:"You can read the whole license here:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'# OpenC3 Evaluation and Educational License\n#\n# Copyright 2023 OpenC3, Inc.\n#\n# This work is licensed for evaluation and educational purposes only.\n# It may NOT be used for formal development, integration and test, operations\n# or any other commercial purpose without the purchase of a commercial license\n# from OpenC3, Inc.\n#\n# The above copyright notice and this permission notice shall be included in all copies\n# or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n'})}),"\n",(0,o.jsx)(n.p,{children:"This license is pretty straight forward, but the key is you can't use this code for any real work leading to a product (Formal Development, Integration and Test, or Operations) unless you switch to purchasing a commercial license."}),"\n",(0,o.jsx)(n.h2,{id:"commercial-license",children:"Commercial License"}),"\n",(0,o.jsx)(n.p,{children:"This license is a signed contract with OpenC3. It allows use of our code for a program under contractual terms where you do not have to follow the AGPLv3."}),"\n",(0,o.jsx)(n.p,{children:"Generally we license to a specific project with terms that allow for unlimited users, and installs as needed by that project. Any code and plugins that you develop under the commercial license can be kept proprietary."}),"\n",(0,o.jsx)(n.p,{children:"These licenses are sold as yearly subscriptions, or as a non-expiring perpetual license. We also offer site licenses, and licenses to support unlimited missions on a government framework architecture."}),"\n",(0,o.jsx)(n.p,{children:"Of course with our commercial license, you also get all the extra functionality of our Enterprise product."}),"\n",(0,o.jsx)(n.h3,{id:"why-you-should-buy-a-commercial-license",children:"Why you should buy a Commercial License"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"You want to save years and tens of millions of dollars developing the same functionality yourself."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"You want all of the Enterprise functionality of COSMOS Enterprise Edition"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsx)(n.li,{children:"User Accounts"}),"\n",(0,o.jsx)(n.li,{children:"Role Based Access Control"}),"\n",(0,o.jsx)(n.li,{children:"LDAP Support"}),"\n",(0,o.jsx)(n.li,{children:"Kubernetes Support"}),"\n",(0,o.jsx)(n.li,{children:"Cloud Deployment Configurations"}),"\n",(0,o.jsx)(n.li,{children:"The right to use CFDP and other Enterprise Only plugins"}),"\n",(0,o.jsx)(n.li,{children:"Grafana Support"}),"\n",(0,o.jsx)(n.li,{children:"Support from the COSMOS Developers"}),"\n",(0,o.jsxs)(n.li,{children:["Lots more - See our ",(0,o.jsx)(n.a,{href:"https://openc3.com/enterprise",children:"Enterprise"})," page"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"You don't want to follow the AGPLv3"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsx)(n.li,{children:"You want to keep the code and plugins you develop proprietary"}),"\n",(0,o.jsx)(n.li,{children:"You don't want to publish an accessible link to your source code"}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"You want to support the continued development and innovation of the COSMOS product"}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:(0,o.jsx)(n.em,{children:"We appreciate all of our commercial customers. You make OpenC3 possible. Thank you."})})}),"\n",(0,o.jsx)(n.h2,{id:"faqs",children:"FAQs"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"I see both Ball Aerospace & Technologies Corp as well as OpenC3, Inc in the copyright headers. What does this mean?"}),"\n",(0,o.jsx)(n.p,{children:"OpenC3, Inc has an intellectual property agreement with BAE (formerly Ball Aerospace & Technologies Corp) which gives us the rights to commercialize the original work that we built at Ball Aerospace. Customers only need to purchase a commercial license from OpenC3."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"What are the limits of the COSMOS Enterprise Edition? How many users can we have? How many times can it be installed?"}),"\n",(0,o.jsx)(n.p,{children:"The COSMOS Enterprise Edition license has no user or installation limits."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"How is the COSMOS Enterprise Edition license enforced?"}),"\n",(0,o.jsx)(n.p,{children:"The COSMOS Enterprise Edition license is enforced through contract only without license managers or additional software controls."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"How is the COSMOS Enterprise Edition license applied? Per company? Per program?"}),"\n",(0,o.jsxs)(n.p,{children:["COSMOS Enterprise Edition is typically licensed to a named mission or group. We also have site licenses, company licenses, and mission ops center licenses. Please contact us at ",(0,o.jsx)(n.a,{href:"mailto:sales@openc3.com",children:"sales@openc3.com"})," for more information."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Do you license to foreign companies? How do you handle ITAR or the EAR?"}),"\n",(0,o.jsxs)(n.p,{children:["We have several international customers and are not subject to ITAR export controls. We are export controlled under the EAR via ECCN 5D002c1. We have a detailed writeup explaining this justification as well as a commodity classification document from the Department of Commerce. Please contact us at ",(0,o.jsx)(n.a,{href:"mailto:sales@openc3.com",children:"sales@openc3.com"})," for more information."]}),"\n"]}),"\n"]})]})}function d(e={}){let{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},2840:function(e,n,s){s.d(n,{Z:function(){return r},a:function(){return l}});var i=s(2784);let o={},t=i.createContext(o);function l(e){let n=i.useContext(t);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:l(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]);
|
@@ -1 +0,0 @@
|
|
1
|
-
"use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["3927"],{929:function(e,r,n){n.r(r),n.d(r,{default:()=>o,frontMatter:()=>l,metadata:()=>i,assets:()=>c,toc:()=>h,contentTitle:()=>d});var i=JSON.parse('{"id":"configuration/plugins","title":"Plugins","description":"Plugin definition file format and keywords","source":"@site/docs/configuration/plugins.md","sourceDirName":"configuration","slug":"/configuration/plugins","permalink":"/tools/staticdocs/docs/configuration/plugins","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/configuration/plugins.md","tags":[],"version":"current","sidebarPosition":2,"frontMatter":{"sidebar_position":2,"title":"Plugins","description":"Plugin definition file format and keywords","sidebar_custom_props":{"myEmoji":"\uD83D\uDD0C"}},"sidebar":"defaultSidebar","previous":{"title":"File Format","permalink":"/tools/staticdocs/docs/configuration/format"},"next":{"title":"Targets","permalink":"/tools/staticdocs/docs/configuration/target"}}'),s=n("2322"),t=n("2840");let l={sidebar_position:2,title:"Plugins",description:"Plugin definition file format and keywords",sidebar_custom_props:{myEmoji:"\uD83D\uDD0C"}},d=void 0,c={},h=[{value:"Introduction",id:"introduction",level:2},{value:"Concepts",id:"concepts",level:2},{value:"Target",id:"target",level:3},{value:"Interface",id:"interface",level:3},{value:"Router",id:"router",level:3},{value:"Tool",id:"tool",level:3},{value:"Microservice",id:"microservice",level:3},{value:"Plugin Directory Structure",id:"plugin-directory-structure",level:2},{value:"plugin.txt Configuration File",id:"plugintxt-configuration-file",level:2},{value:"VARIABLE",id:"variable",level:2},{value:"NEEDS_DEPENDENCIES",id:"needs_dependencies",level:2},{value:"INTERFACE",id:"interface-1",level:2},{value:"INTERFACE Modifiers",id:"interface-modifiers",level:2},{value:"MAP_TARGET",id:"map_target",level:3},{value:"MAP_CMD_TARGET",id:"map_cmd_target",level:3},{value:"MAP_TLM_TARGET",id:"map_tlm_target",level:3},{value:"DONT_CONNECT",id:"dont_connect",level:3},{value:"DONT_RECONNECT",id:"dont_reconnect",level:3},{value:"RECONNECT_DELAY",id:"reconnect_delay",level:3},{value:"DISABLE_DISCONNECT",id:"disable_disconnect",level:3},{value:"LOG_RAW",id:"log_raw",level:3},{value:"LOG_STREAM",id:"log_stream",level:3},{value:"PROTOCOL",id:"protocol",level:3},{value:"OPTION",id:"option",level:3},{value:"SECRET",id:"secret",level:3},{value:"ENV",id:"env",level:3},{value:"WORK_DIR",id:"work_dir",level:3},{value:"PORT",id:"port",level:3},{value:"CMD",id:"cmd",level:3},{value:"CONTAINER",id:"container",level:3},{value:"ROUTE_PREFIX",id:"route_prefix",level:3},{value:"SHARD",id:"shard",level:3},{value:"ROUTER",id:"router-1",level:2},{value:"TARGET",id:"target-1",level:2},{value:"TARGET Modifiers",id:"target-modifiers",level:2},{value:"CMD_BUFFER_DEPTH",id:"cmd_buffer_depth",level:3},{value:"CMD_LOG_CYCLE_TIME",id:"cmd_log_cycle_time",level:3},{value:"CMD_LOG_CYCLE_SIZE",id:"cmd_log_cycle_size",level:3},{value:"CMD_LOG_RETAIN_TIME",id:"cmd_log_retain_time",level:3},{value:"CMD_DECOM_LOG_CYCLE_TIME",id:"cmd_decom_log_cycle_time",level:3},{value:"CMD_DECOM_LOG_CYCLE_SIZE",id:"cmd_decom_log_cycle_size",level:3},{value:"CMD_DECOM_LOG_RETAIN_TIME",id:"cmd_decom_log_retain_time",level:3},{value:"TLM_BUFFER_DEPTH",id:"tlm_buffer_depth",level:3},{value:"TLM_LOG_CYCLE_TIME",id:"tlm_log_cycle_time",level:3},{value:"TLM_LOG_CYCLE_SIZE",id:"tlm_log_cycle_size",level:3},{value:"TLM_LOG_RETAIN_TIME",id:"tlm_log_retain_time",level:3},{value:"TLM_DECOM_LOG_CYCLE_TIME",id:"tlm_decom_log_cycle_time",level:3},{value:"TLM_DECOM_LOG_CYCLE_SIZE",id:"tlm_decom_log_cycle_size",level:3},{value:"TLM_DECOM_LOG_RETAIN_TIME",id:"tlm_decom_log_retain_time",level:3},{value:"REDUCED_MINUTE_LOG_RETAIN_TIME",id:"reduced_minute_log_retain_time",level:3},{value:"REDUCED_HOUR_LOG_RETAIN_TIME",id:"reduced_hour_log_retain_time",level:3},{value:"REDUCED_DAY_LOG_RETAIN_TIME",id:"reduced_day_log_retain_time",level:3},{value:"LOG_RETAIN_TIME",id:"log_retain_time",level:3},{value:"REDUCED_LOG_RETAIN_TIME",id:"reduced_log_retain_time",level:3},{value:"CLEANUP_POLL_TIME",id:"cleanup_poll_time",level:3},{value:"REDUCER_DISABLE",id:"reducer_disable",level:3},{value:"REDUCER_MAX_CPU_UTILIZATION",id:"reducer_max_cpu_utilization",level:3},{value:"TARGET_MICROSERVICE",id:"target_microservice",level:3},{value:"PACKET",id:"packet",level:3},{value:"DISABLE_ERB",id:"disable_erb",level:3},{value:"SHARD",id:"shard-1",level:3},{value:"MICROSERVICE",id:"microservice-1",level:2},{value:"MICROSERVICE Modifiers",id:"microservice-modifiers",level:2},{value:"ENV",id:"env-1",level:3},{value:"WORK_DIR",id:"work_dir-1",level:3},{value:"PORT",id:"port-1",level:3},{value:"TOPIC",id:"topic",level:3},{value:"TARGET_NAME",id:"target_name",level:3},{value:"CMD",id:"cmd-1",level:3},{value:"OPTION",id:"option-1",level:3},{value:"CONTAINER",id:"container-1",level:3},{value:"SECRET",id:"secret-1",level:3},{value:"ROUTE_PREFIX",id:"route_prefix-1",level:3},{value:"DISABLE_ERB",id:"disable_erb-1",level:3},{value:"SHARD",id:"shard-2",level:3},{value:"STOPPED",id:"stopped",level:3},{value:"TOOL",id:"tool-1",level:2},{value:"TOOL Modifiers",id:"tool-modifiers",level:2},{value:"URL",id:"url",level:3},{value:"INLINE_URL",id:"inline_url",level:3},{value:"WINDOW",id:"window",level:3},{value:"ICON",id:"icon",level:3},{value:"CATEGORY",id:"category",level:3},{value:"SHOWN",id:"shown",level:3},{value:"POSITION",id:"position",level:3},{value:"DISABLE_ERB",id:"disable_erb-2",level:3},{value:"IMPORT_MAP_ITEM",id:"import_map_item",level:3},{value:"WIDGET",id:"widget",level:2},{value:"WIDGET Modifiers",id:"widget-modifiers",level:2},{value:"DISABLE_ERB",id:"disable_erb-3",level:3}];function a(e){let r={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(r.p,{children:"This document provides the information necessary to configure a COSMOS plugin. Plugins are how you configure and extend COSMOS."}),"\n",(0,s.jsx)(r.p,{children:"Plugins are where you define targets (and their corresponding command and telemetry packet definitions), where you configure the interfaces needed to talk to targets, where you can define routers to stream raw data out of COSMOS, how you can add new tools to the COSMOS user interface, and how you can run additional microservices to provide new functionality."}),"\n",(0,s.jsx)(r.p,{children:"Each plugin is built as a Ruby gem and thus has a plugin.gemspec file which builds it. Plugins have a plugin.txt file which declares all the variables used by the plugin and how to interface to the target(s) it contains."}),"\n",(0,s.jsx)(r.h2,{id:"concepts",children:"Concepts"}),"\n",(0,s.jsx)(r.h3,{id:"target",children:"Target"}),"\n",(0,s.jsx)(r.p,{children:"Targets are the external pieces of hardware and/or software that COSMOS communicates with. These are things like Front End Processors (FEPs), ground support equipment (GSE), custom software tools, and pieces of hardware like satellites themselves. A target is anything that COSMOS can send commands to and receive telemetry from."}),"\n",(0,s.jsx)(r.h3,{id:"interface",children:"Interface"}),"\n",(0,s.jsx)(r.p,{children:"Interfaces implement the physical connection to one or more targets. They are typically ethernet connections implemented using TCP or UDP but can be other connections like serial ports. Interfaces send commands to targets and receive telemetry from targets."}),"\n",(0,s.jsx)(r.h3,{id:"router",children:"Router"}),"\n",(0,s.jsx)(r.p,{children:"Routers flow streams of telemetry packets out of COSMOS and receive streams of commands into COSMOS. The commands are forwarded by COSMOS to associated interfaces. Telemetry comes from associated interfaces."}),"\n",(0,s.jsx)(r.h3,{id:"tool",children:"Tool"}),"\n",(0,s.jsx)(r.p,{children:"COSMOS Tools are web-based applications the communicate with the COSMOS APIs to perform takes like displaying telemetry, sending commands, and running scripts."}),"\n",(0,s.jsx)(r.h3,{id:"microservice",children:"Microservice"}),"\n",(0,s.jsx)(r.p,{children:"Microservices are persistent running backend code that runs within the COSMOS environment. They can process data and perform other useful tasks."}),"\n",(0,s.jsx)(r.h2,{id:"plugin-directory-structure",children:"Plugin Directory Structure"}),"\n",(0,s.jsxs)(r.p,{children:["COSMOS plugins have a well-defined directory structure described in detail in the ",(0,s.jsx)(r.a,{href:"../getting-started/generators",children:"Code Generator"})," documentation."]}),"\n",(0,s.jsx)(r.h2,{id:"plugintxt-configuration-file",children:"plugin.txt Configuration File"}),"\n",(0,s.jsx)(r.p,{children:"A plugin.txt configuration file is required for any COSMOS plugin. It declares the contents of the plugin and provides variables that allow the plugin to be configured at the time it is initially installed or upgraded.\nThis file follows the standard COSMOS configuration file format of keywords followed by zero or more space separated parameters. The following keywords are supported by the plugin.txt config file:"}),"\n",(0,s.jsx)(r.h2,{id:"variable",children:"VARIABLE"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Define a configurable variable for the plugin"})}),"\n",(0,s.jsx)(r.p,{children:"The VARIABLE keyword defines a variable that will be requested for the user to enter during plugin installation. Variables can be used to handle details of targets that are user defined such as specific IP addresses and ports. Variables should also be used to allow users to rename targets to whatever name they want and support multiple installations of the same target with different names. Variables can be used later in plugin.txt or in any other configuration file included in a plugin using Ruby ERB syntax. The variables are assigned to accessible local variables in the file. At a high level, ERB allows you to run Ruby code in configuration files."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Variable Name"}),(0,s.jsx)(r.td,{children:"The name of the variable"}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Default Value"}),(0,s.jsx)(r.td,{children:"Default value of the variable"}),(0,s.jsx)(r.td,{children:"True"})]})]})]}),"\n",(0,s.jsx)(r.h2,{id:"needs_dependencies",children:"NEEDS_DEPENDENCIES"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.5.0)"}),(0,s.jsx)(r.strong,{children:"Indicates the plugin needs dependencies and sets the GEM_HOME environment variable"})]}),"\n",(0,s.jsx)(r.p,{children:"If the plugin has a top level lib folder or lists runtime dependencies in the gemspec, NEEDS_DEPENDENCIES is effectively already set. Note that in Enterprise Edition, having NEEDS_DEPENDENCIES adds the NFS volume mount to the Kubernetes pod."}),"\n",(0,s.jsx)(r.h2,{id:"interface-1",children:"INTERFACE"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Defines a connection to a physical target"})}),"\n",(0,s.jsx)(r.p,{children:"Interfaces are what OpenC3 uses to talk to a particular piece of hardware. Interfaces require a Ruby or Python file which implements all the interface methods necessary to talk to the hardware. OpenC3 defines many built in interfaces or you can define your own as long as it implements the interface protocol."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Interface Name"}),(0,s.jsx)(r.td,{children:"Name of the interface. This name will appear in the Interfaces tab of the Server and is also referenced by other keywords. The OpenC3 convention is to name interfaces after their targets with '_INT' appended to the name, e.g. INST_INT for the INST target."}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Filename"}),(0,s.jsxs)(r.td,{children:["Ruby or Python file to use when instantiating the interface.",(0,s.jsx)("br",{}),(0,s.jsx)("br",{}),"Valid Values: ",(0,s.jsx)("span",{class:"values",children:"tcpip_client_interface, tcpip_server_interface, udp_interface, serial_interface"})]}),(0,s.jsx)(r.td,{children:"True"})]})]})]}),"\n",(0,s.jsxs)(r.p,{children:["Additional parameters are required. Please see the ",(0,s.jsx)(r.a,{href:"/tools/staticdocs/docs/configuration/interfaces",children:"Interfaces"})," documentation for more details."]}),"\n",(0,s.jsx)(r.h2,{id:"interface-modifiers",children:"INTERFACE Modifiers"}),"\n",(0,s.jsx)(r.p,{children:"The following keywords must follow a INTERFACE keyword."}),"\n",(0,s.jsx)(r.h3,{id:"map_target",children:"MAP_TARGET"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Maps a target name to an interface"})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Target Name"}),(0,s.jsx)(r.td,{children:"Target name to map to this interface"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.p,{children:"Ruby Example:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"INTERFACE DATA_INT tcpip_client_interface.rb host.docker.internal 8080 8081 10.0 nil BURST\n MAP_TARGET DATA\n"})}),"\n",(0,s.jsx)(r.p,{children:"Python Example:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-python",children:"INTERFACE DATA_INT openc3/interfaces/tcpip_client_interface.py host.docker.internal 8080 8081 10.0 nil BURST\n MAP_TARGET DATA\n"})}),"\n",(0,s.jsx)(r.h3,{id:"map_cmd_target",children:"MAP_CMD_TARGET"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.2.0)"}),(0,s.jsx)(r.strong,{children:"Maps a target name to an interface for commands only"})]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Target Name"}),(0,s.jsx)(r.td,{children:"Command target name to map to this interface"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.p,{children:"Ruby Example:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"INTERFACE CMD_INT tcpip_client_interface.rb host.docker.internal 8080 8081 10.0 nil BURST\n MAP_CMD_TARGET DATA # Only DATA commands go on the CMD_INT interface\n"})}),"\n",(0,s.jsx)(r.p,{children:"Python Example:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-python",children:"INTERFACE CMD_INT openc3/interfaces/tcpip_client_interface.py host.docker.internal 8080 8081 10.0 nil BURST\n MAP_CMD_TARGET DATA # Only DATA commands go on the CMD_INT interface\n"})}),"\n",(0,s.jsx)(r.h3,{id:"map_tlm_target",children:"MAP_TLM_TARGET"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.2.0)"}),(0,s.jsx)(r.strong,{children:"Maps a target name to an interface for telemetry only"})]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Target Name"}),(0,s.jsx)(r.td,{children:"Telemetry target name to map to this interface"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.p,{children:"Ruby Example:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"INTERFACE TLM_INT tcpip_client_interface.rb host.docker.internal 8080 8081 10.0 nil BURST\n MAP_TLM_TARGET DATA # Only DATA telemetry received on TLM_INT interface\n"})}),"\n",(0,s.jsx)(r.p,{children:"Python Example:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-python",children:"INTERFACE TLM_INT openc3/interfaces/tcpip_client_interface.py host.docker.internal 8080 8081 10.0 nil BURST\n MAP_TLM_TARGET DATA # Only DATA telemetry received on TLM_INT interface\n"})}),"\n",(0,s.jsx)(r.h3,{id:"dont_connect",children:"DONT_CONNECT"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Server will not automatically try to connect to the interface at startup"})}),"\n",(0,s.jsx)(r.h3,{id:"dont_reconnect",children:"DONT_RECONNECT"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Server will not try to reconnect to the interface if the connection is lost"})}),"\n",(0,s.jsx)(r.h3,{id:"reconnect_delay",children:"RECONNECT_DELAY"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Reconnect delay in seconds"})}),"\n",(0,s.jsx)(r.p,{children:"If DONT_RECONNECT is not present the Server will try to reconnect to an interface if the connection is lost. Reconnect delay sets the interval in seconds between reconnect tries."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Delay"}),(0,s.jsx)(r.td,{children:"Delay in seconds between reconnect attempts. The default is 15 seconds."}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"disable_disconnect",children:"DISABLE_DISCONNECT"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Disable the Disconnect button on the Interfaces tab in the Server"})}),"\n",(0,s.jsx)(r.p,{children:"Use this keyword to prevent the user from disconnecting from the interface. This is typically used in a 'production' environment where you would not want the user to inadvertently disconnect from a target."}),"\n",(0,s.jsx)(r.h3,{id:"log_raw",children:"LOG_RAW"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Deprecated, use LOG_STREAM"})}),"\n",(0,s.jsx)(r.h3,{id:"log_stream",children:"LOG_STREAM"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.5.2)"}),(0,s.jsx)(r.strong,{children:"Log all data on the interface exactly as it is sent and received"})]}),"\n",(0,s.jsx)(r.p,{children:"LOG_STREAM does not add any OpenC3 headers and thus can not be read by OpenC3 tools. It is primarily useful for low level debugging of an interface. You will have to manually parse these logs yourself using a hex editor or other application."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Cycle Time"}),(0,s.jsx)(r.td,{children:"Amount of time to wait before cycling the log file. Default is 10 min. If nil refer to Cycle Hour and Cycle Minute."}),(0,s.jsx)(r.td,{children:"False"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Cycle Size"}),(0,s.jsx)(r.td,{children:"Amount of data to write before cycling the log file. Default is 50MB."}),(0,s.jsx)(r.td,{children:"False"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Cycle Hour"}),(0,s.jsx)(r.td,{children:"The time at which to cycle the log. Combined with Cycle Minute to cycle the log daily at the specified time. If nil, the log will be cycled hourly at the specified Cycle Minute. Only applies if Cycle Time is nil."}),(0,s.jsx)(r.td,{children:"False"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Cycle Minute"}),(0,s.jsx)(r.td,{children:"See Cycle Hour."}),(0,s.jsx)(r.td,{children:"False"})]})]})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"INTERFACE EXAMPLE example_interface.rb\n # Override the default log time of 600\n LOG_STREAM 60\n"})}),"\n",(0,s.jsx)(r.h3,{id:"protocol",children:"PROTOCOL"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 4.0.0)"}),(0,s.jsx)(r.strong,{children:"Protocols modify the interface by processing the data"})]}),"\n",(0,s.jsxs)(r.p,{children:["Protocols can be either READ, WRITE, or READ_WRITE. READ protocols act on the data received by the interface while write acts on the data before it is sent out. READ_WRITE applies the protocol to both reading and writing.",(0,s.jsx)("br",{}),(0,s.jsx)("br",{})," For information on creating your own custom protocol please see ",(0,s.jsx)(r.a,{href:"/tools/staticdocs/docs/configuration/protocols",children:"Protocols"})]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Type"}),(0,s.jsxs)(r.td,{children:["Whether to apply the protocol on incoming data, outgoing data, or both",(0,s.jsx)("br",{}),(0,s.jsx)("br",{}),"Valid Values: ",(0,s.jsx)("span",{class:"values",children:"READ, WRITE, READ_WRITE"})]}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Protocol Filename or Classname"}),(0,s.jsx)(r.td,{children:"Ruby or Python filename or class name which implements the protocol"}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Protocol specific parameters"}),(0,s.jsx)(r.td,{children:"Additional parameters used by the protocol"}),(0,s.jsx)(r.td,{children:"False"})]})]})]}),"\n",(0,s.jsx)(r.p,{children:"Ruby Example:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"INTERFACE DATA_INT tcpip_client_interface.rb host.docker.internal 8080 8081 10.0 nil nil\n MAP_TARGET DATA\n # Rather than defining the LENGTH protocol on the INTERFACE line we define it here\n PROTOCOL READ LengthProtocol 0 16 0 1 BIG_ENDIAN 4 0xBA5EBA11\n"})}),"\n",(0,s.jsx)(r.p,{children:"Python Example:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-python",children:"INTERFACE DATA_INT openc3/interfaces/tcpip_client_interface.py host.docker.internal 8080 8081 10.0 nil BURST\n MAP_TARGET DATA\n PROTOCOL READ IgnorePacketProtocol INST IMAGE # Drop all INST IMAGE packets\n"})}),"\n",(0,s.jsx)(r.h3,{id:"option",children:"OPTION"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Set a parameter on an interface"})}),"\n",(0,s.jsx)(r.p,{children:"When an option is set the interface class calls the set_option method. Custom interfaces can override set_option to handle any additional options they want."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Name"}),(0,s.jsx)(r.td,{children:"The option to set. OpenC3 defines several options on the core provided interfaces. The SerialInterface defines FLOW_CONTROL which can be NONE (default) or RTSCTS and DATA_BITS which changes the data bits of the serial interface. The TcpipServerInterface and HttpServerInterface define LISTEN_ADDRESS which is the IP address to accept connections on (default 0.0.0.0)."}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Parameters"}),(0,s.jsx)(r.td,{children:"Parameters to pass to the option"}),(0,s.jsx)(r.td,{children:"False"})]})]})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"INTERFACE SERIAL_INT serial_interface.rb COM1 COM1 115200 NONE 1 10.0 nil\n OPTION FLOW_CONTROL RTSCTS\n OPTION DATA_BITS 8\nROUTER SERIAL_ROUTER tcpip_server_interface.rb 2950 2950 10.0 nil BURST\n ROUTE SERIAL_INT\n OPTION LISTEN_ADDRESS 127.0.0.1\n"})}),"\n",(0,s.jsx)(r.h3,{id:"secret",children:"SECRET"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.3.0)"}),(0,s.jsx)(r.strong,{children:"Define a secret needed by this interface"})]}),"\n",(0,s.jsxs)(r.p,{children:["Defines a secret for this interface and optionally assigns its value to an option. For more information see ",(0,s.jsx)(r.a,{href:"/docs/tools/admin#secrets",children:"Admin Secrets"}),"."]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Type"}),(0,s.jsx)(r.td,{children:"ENV or FILE. ENV will mount the secret into an environment variable. FILE mounts the secret into a file."}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Secret Name"}),(0,s.jsxs)(r.td,{children:["The name of the secret to retrieve from the Admin / Secrets tab. For more information see ",(0,s.jsx)(r.a,{href:"/docs/tools/admin#secrets",children:"Admin Secrets"}),"."]}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Environment Variable or File Path"}),(0,s.jsx)(r.td,{children:"Environment variable name or file path to store secret. Note that if you use the Option Name to set an option to the secret value, this value doesn't really matter as long as it is unique."}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Option Name"}),(0,s.jsx)(r.td,{children:"Interface option to pass the secret value. This is the primary way to pass secrets to interfaces."}),(0,s.jsx)(r.td,{children:"False"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Secret Store Name"}),(0,s.jsx)(r.td,{children:"Name of the secret store for stores with multipart keys"}),(0,s.jsx)(r.td,{children:"False"})]})]})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:'SECRET ENV USERNAME ENV_USERNAME USERNAME\nSECRET FILE KEY "/tmp/DATA/cert" KEY\n'})}),"\n",(0,s.jsx)(r.h3,{id:"env",children:"ENV"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.7.0)"}),(0,s.jsx)(r.strong,{children:"Sets an environment variable in the microservice."})]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Key"}),(0,s.jsx)(r.td,{children:"Environment variable name"}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Value"}),(0,s.jsx)(r.td,{children:"Environment variable value"}),(0,s.jsx)(r.td,{children:"True"})]})]})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"ENV COMPANY OpenC3\n"})}),"\n",(0,s.jsx)(r.h3,{id:"work_dir",children:"WORK_DIR"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.7.0)"}),(0,s.jsx)(r.strong,{children:"Set the working directory"})]}),"\n",(0,s.jsx)(r.p,{children:"Working directory to run the microservice CMD in. Can be a path relative to the microservice folder in the plugin, or an absolute path in the container the microservice runs in."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Directory"}),(0,s.jsx)(r.td,{children:"Working directory to run the microservice CMD in. Can be a path relative to the microservice folder in the plugin, or an absolute path in the container the microservice runs in."}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"WORK_DIR '/openc3/lib/openc3/microservices'\n"})}),"\n",(0,s.jsx)(r.h3,{id:"port",children:"PORT"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.7.0)"}),(0,s.jsx)(r.strong,{children:"Open port for the microservice"})]}),"\n",(0,s.jsx)(r.p,{children:"Kubernetes needs a Service to be applied to open a port so this is required for Kubernetes support"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Number"}),(0,s.jsx)(r.td,{children:"Port number"}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Protocol"}),(0,s.jsx)(r.td,{children:"Port protocol. Default is TCP."}),(0,s.jsx)(r.td,{children:"False"})]})]})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"PORT 7272\n"})}),"\n",(0,s.jsx)(r.h3,{id:"cmd",children:"CMD"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.7.0)"}),(0,s.jsx)(r.strong,{children:"Command line to execute to run the microservice."})]}),"\n",(0,s.jsx)(r.p,{children:"Command line to execute to run the microservice."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Args"}),(0,s.jsx)(r.td,{children:"One or more arguments to exec to run the microservice."}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.p,{children:"Ruby Example:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"CMD ruby interface_microservice.rb DEFAULT__INTERFACE__INT1\n"})}),"\n",(0,s.jsx)(r.p,{children:"Python Example:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-python",children:"CMD python interface_microservice.py DEFAULT__INTERFACE__INT1\n"})}),"\n",(0,s.jsx)(r.h3,{id:"container",children:"CONTAINER"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.7.0)"}),(0,s.jsx)(r.strong,{children:"Docker Container"})]}),"\n",(0,s.jsx)(r.p,{children:"Container to execute and run the microservice in. Only used in COSMOS Enterprise Edition."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Args"}),(0,s.jsx)(r.td,{children:"Name of the container"}),(0,s.jsx)(r.td,{children:"False"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"route_prefix",children:"ROUTE_PREFIX"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.7.0)"}),(0,s.jsx)(r.strong,{children:"Prefix of route"})]}),"\n",(0,s.jsx)(r.p,{children:"Prefix of route to the microservice to expose externally with Traefik"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Route Prefix"}),(0,s.jsx)(r.td,{children:"Route prefix. Must be unique across all scopes. Something like /myprefix"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"ROUTE_PREFIX /interface\n"})}),"\n",(0,s.jsx)(r.h3,{id:"shard",children:"SHARD"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 6.0.0)"}),(0,s.jsx)(r.strong,{children:"Operator shard to run target microservices on"})]}),"\n",(0,s.jsx)(r.p,{children:"Operator Shard. Only used if running multiple operator containers typically in Kubernetes"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Shard"}),(0,s.jsx)(r.td,{children:"Shard number starting from 0"}),(0,s.jsx)(r.td,{children:"False"})]})})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"SHARD 0\n"})}),"\n",(0,s.jsx)(r.h2,{id:"router-1",children:"ROUTER"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Create router to receive commands and output telemetry packets from one or more interfaces"})}),"\n",(0,s.jsx)(r.p,{children:"Creates an router which receives command packets from their remote clients and sends them to associated interfaces. They receive telemetry packets from their interfaces and send them to their remote clients. This allows routers to be intermediaries between an external client and an actual device."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Name"}),(0,s.jsx)(r.td,{children:"Name of the router"}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Filename"}),(0,s.jsxs)(r.td,{children:["Ruby or Python file to use when instantiating the interface.",(0,s.jsx)("br",{}),(0,s.jsx)("br",{}),"Valid Values: ",(0,s.jsx)("span",{class:"values",children:"tcpip_client_interface, tcpip_server_interface, udp_interface, serial_interface"})]}),(0,s.jsx)(r.td,{children:"True"})]})]})]}),"\n",(0,s.jsxs)(r.p,{children:["Additional parameters are required. Please see the ",(0,s.jsx)(r.a,{href:"/tools/staticdocs/docs/configuration/interfaces",children:"Interfaces"})," documentation for more details."]}),"\n",(0,s.jsx)(r.h2,{id:"target-1",children:"TARGET"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Defines a new target"})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Folder Name"}),(0,s.jsx)(r.td,{children:"The target folder"}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Name"}),(0,s.jsx)(r.td,{children:"The target name. While this is almost always the same as Folder Name it can be different to create multiple targets based on the same target folder."}),(0,s.jsx)(r.td,{children:"True"})]})]})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"TARGET INST INST\n"})}),"\n",(0,s.jsx)(r.h2,{id:"target-modifiers",children:"TARGET Modifiers"}),"\n",(0,s.jsx)(r.p,{children:"The following keywords must follow a TARGET keyword."}),"\n",(0,s.jsx)(r.h3,{id:"cmd_buffer_depth",children:"CMD_BUFFER_DEPTH"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.2.0)"}),(0,s.jsx)(r.strong,{children:"Number of commands to buffer to ensure logged in order"})]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Buffer Depth"}),(0,s.jsx)(r.td,{children:"Buffer depth in packets (Default = 5)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"cmd_log_cycle_time",children:"CMD_LOG_CYCLE_TIME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Command binary logs can be cycled on a time interval."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Time"}),(0,s.jsx)(r.td,{children:"Maximum time between files in seconds (default = 600)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"cmd_log_cycle_size",children:"CMD_LOG_CYCLE_SIZE"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Command binary logs can be cycled after a certain log file size is reached."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Size"}),(0,s.jsx)(r.td,{children:"Maximum file size in bytes (default = 50_000_000)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"cmd_log_retain_time",children:"CMD_LOG_RETAIN_TIME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"How long to keep raw command logs in seconds."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Time"}),(0,s.jsx)(r.td,{children:"Number of seconds to keep raw command logs (default = nil = Forever)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"cmd_decom_log_cycle_time",children:"CMD_DECOM_LOG_CYCLE_TIME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Command decommutation logs can be cycled on a time interval."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Time"}),(0,s.jsx)(r.td,{children:"Maximum time between files in seconds (default = 600)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"cmd_decom_log_cycle_size",children:"CMD_DECOM_LOG_CYCLE_SIZE"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Command decommutation logs can be cycled after a certain log file size is reached."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Size"}),(0,s.jsx)(r.td,{children:"Maximum file size in bytes (default = 50_000_000)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"cmd_decom_log_retain_time",children:"CMD_DECOM_LOG_RETAIN_TIME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"How long to keep decom command logs in seconds."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Time"}),(0,s.jsx)(r.td,{children:"Number of seconds to keep decom command logs (default = nil = Forever)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"tlm_buffer_depth",children:"TLM_BUFFER_DEPTH"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.2.0)"}),(0,s.jsx)(r.strong,{children:"Number of telemetry packets to buffer to ensure logged in order"})]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Buffer Depth"}),(0,s.jsx)(r.td,{children:"Buffer depth in packets (Default = 60)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"tlm_log_cycle_time",children:"TLM_LOG_CYCLE_TIME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Telemetry binary logs can be cycled on a time interval."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Time"}),(0,s.jsx)(r.td,{children:"Maximum time between files in seconds (default = 600)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"tlm_log_cycle_size",children:"TLM_LOG_CYCLE_SIZE"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Telemetry binary logs can be cycled after a certain log file size is reached."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Size"}),(0,s.jsx)(r.td,{children:"Maximum file size in bytes (default = 50_000_000)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"tlm_log_retain_time",children:"TLM_LOG_RETAIN_TIME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"How long to keep raw telemetry logs in seconds."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Time"}),(0,s.jsx)(r.td,{children:"Number of seconds to keep raw telemetry logs (default = nil = Forever)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"tlm_decom_log_cycle_time",children:"TLM_DECOM_LOG_CYCLE_TIME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Telemetry decommutation logs can be cycled on a time interval."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Time"}),(0,s.jsx)(r.td,{children:"Maximum time between files in seconds (default = 600)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"tlm_decom_log_cycle_size",children:"TLM_DECOM_LOG_CYCLE_SIZE"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Telemetry decommutation logs can be cycled after a certain log file size is reached."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Size"}),(0,s.jsx)(r.td,{children:"Maximum file size in bytes (default = 50_000_000)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"tlm_decom_log_retain_time",children:"TLM_DECOM_LOG_RETAIN_TIME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"How long to keep decom telemetry logs in seconds."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Time"}),(0,s.jsx)(r.td,{children:"Number of seconds to keep decom telemetry logs (default = nil = Forever)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"reduced_minute_log_retain_time",children:"REDUCED_MINUTE_LOG_RETAIN_TIME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"How long to keep reduced minute telemetry logs in seconds."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Time"}),(0,s.jsx)(r.td,{children:"Number of seconds to keep reduced minute telemetry logs (default = nil = Forever)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"reduced_hour_log_retain_time",children:"REDUCED_HOUR_LOG_RETAIN_TIME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"How long to keep reduced hour telemetry logs in seconds."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Time"}),(0,s.jsx)(r.td,{children:"Number of seconds to keep reduced hour telemetry logs (default = nil = Forever)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"reduced_day_log_retain_time",children:"REDUCED_DAY_LOG_RETAIN_TIME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"How long to keep reduced day telemetry logs in seconds."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Time"}),(0,s.jsx)(r.td,{children:"Number of seconds to keep reduced day telemetry logs (default = nil = Forever)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"log_retain_time",children:"LOG_RETAIN_TIME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"How long to keep all regular telemetry logs in seconds."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Time"}),(0,s.jsx)(r.td,{children:"Number of seconds to keep all regular telemetry logs (default = nil = Forever)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"reduced_log_retain_time",children:"REDUCED_LOG_RETAIN_TIME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"How long to keep all reduced telemetry logs in seconds."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Time"}),(0,s.jsx)(r.td,{children:"Number of seconds to keep all reduced telemetry logs (default = nil = Forever)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"cleanup_poll_time",children:"CLEANUP_POLL_TIME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Period at which to run the cleanup process."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Time"}),(0,s.jsx)(r.td,{children:"Number of seconds between runs of the cleanup process (default = 600 = 10 minutes)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"reducer_disable",children:"REDUCER_DISABLE"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Disables the data reduction microservice for the target"})}),"\n",(0,s.jsx)(r.h3,{id:"reducer_max_cpu_utilization",children:"REDUCER_MAX_CPU_UTILIZATION"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Maximum amount of CPU utilization to apply to data reduction"})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Percentage"}),(0,s.jsx)(r.td,{children:"0 to 100 percent (default = 30)"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"target_microservice",children:"TARGET_MICROSERVICE"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.2.0)"}),(0,s.jsx)(r.strong,{children:"Breaks a target microservice out into its own process."})]}),"\n",(0,s.jsx)(r.p,{children:"Can be used to give more resources to processing that is falling behind. If defined multiple times for the same type, will create multiple processes. Each process can be given specific packets to process with the PACKET keyword."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Type"}),(0,s.jsx)(r.td,{children:"The target microservice type. Must be one of DECOM, COMMANDLOG, DECOMCMDLOG, PACKETLOG, DECOMLOG, REDUCER, or CLEANUP"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"packet",children:"PACKET"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.2.0)"}),(0,s.jsx)(r.strong,{children:"Packet Name to allocate to the current TARGET_MICROSERVICE."})]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Packet Name"}),(0,s.jsx)(r.td,{children:"The packet name. Does not apply to REDUCER or CLEANUP target microservice types."}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"disable_erb",children:"DISABLE_ERB"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.12.0)"}),(0,s.jsx)(r.strong,{children:"Disable ERB processing"})]}),"\n",(0,s.jsx)(r.p,{children:"Disable ERB processing for the entire target or a set of regular expressions over its filenames"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Regex"}),(0,s.jsx)(r.td,{children:"Regex to match against filenames. If match, then no ERB processing"}),(0,s.jsx)(r.td,{children:"False"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"shard-1",children:"SHARD"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 6.0.0)"}),(0,s.jsx)(r.strong,{children:"Operator shard to run target microservices on"})]}),"\n",(0,s.jsx)(r.p,{children:"Operator Shard. Only used if running multiple operator containers typically in Kubernetes"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Shard"}),(0,s.jsx)(r.td,{children:"Shard number starting from 0"}),(0,s.jsx)(r.td,{children:"False"})]})})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"SHARD 0\n"})}),"\n",(0,s.jsx)(r.h2,{id:"microservice-1",children:"MICROSERVICE"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Defines a new microservice"})}),"\n",(0,s.jsx)(r.p,{children:"Defines a microservice that the plugin adds to the OpenC3 system. Microservices are background software processes that perform persistent processing."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Microservice Folder Name"}),(0,s.jsx)(r.td,{children:"The exact name of the microservice folder in the plugin. ie. microservices/MicroserviceFolderName"}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Microservice Name"}),(0,s.jsx)(r.td,{children:"The specific name of this instance of the microservice in the OpenC3 system"}),(0,s.jsx)(r.td,{children:"True"})]})]})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"MICROSERVICE EXAMPLE openc3-example\n"})}),"\n",(0,s.jsx)(r.h2,{id:"microservice-modifiers",children:"MICROSERVICE Modifiers"}),"\n",(0,s.jsx)(r.p,{children:"The following keywords must follow a MICROSERVICE keyword."}),"\n",(0,s.jsx)(r.h3,{id:"env-1",children:"ENV"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Sets an environment variable in the microservice."})}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Key"}),(0,s.jsx)(r.td,{children:"Environment variable name"}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Value"}),(0,s.jsx)(r.td,{children:"Environment variable value"}),(0,s.jsx)(r.td,{children:"True"})]})]})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"MICROSERVICE EXAMPLE openc3-example\n ENV COMPANY OpenC3\n"})}),"\n",(0,s.jsx)(r.h3,{id:"work_dir-1",children:"WORK_DIR"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Set the working directory"})}),"\n",(0,s.jsx)(r.p,{children:"Working directory to run the microservice CMD in. Can be a path relative to the microservice folder in the plugin, or an absolute path in the container the microservice runs in."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Directory"}),(0,s.jsx)(r.td,{children:"Working directory to run the microservice CMD in. Can be a path relative to the microservice folder in the plugin, or an absolute path in the container the microservice runs in."}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"MICROSERVICE EXAMPLE openc3-example\n WORK_DIR .\n"})}),"\n",(0,s.jsx)(r.h3,{id:"port-1",children:"PORT"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.0.10)"}),(0,s.jsx)(r.strong,{children:"Open port for the microservice"})]}),"\n",(0,s.jsx)(r.p,{children:"Kubernetes needs a Service to be applied to open a port so this is required for Kubernetes support"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Number"}),(0,s.jsx)(r.td,{children:"Port number"}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Protocol"}),(0,s.jsx)(r.td,{children:"Port protocol. Default is TCP."}),(0,s.jsx)(r.td,{children:"False"})]})]})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"MICROSERVICE EXAMPLE openc3-example\n PORT 7272\n"})}),"\n",(0,s.jsx)(r.h3,{id:"topic",children:"TOPIC"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Associate a Redis topic"})}),"\n",(0,s.jsx)(r.p,{children:"Redis topic to associate with this microservice. Standard OpenC3 microservices such as decom_microservice use this information to know what packet streams to subscribe to. The TOPIC keyword can be used as many times as necessary to associate all needed topics."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Topic Name"}),(0,s.jsx)(r.td,{children:"Redis Topic to associate with the microservice"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"MICROSERVICE EXAMPLE openc3-example\n # Manually assigning topics is an advanced topic and requires\n # intimate knowledge of the internal COSMOS data structures.\n TOPIC DEFAULT__openc3_log_messages\n TOPIC DEFAULT__TELEMETRY__EXAMPLE__STATUS\n"})}),"\n",(0,s.jsx)(r.h3,{id:"target_name",children:"TARGET_NAME"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Associate a OpenC3 target"})}),"\n",(0,s.jsx)(r.p,{children:"OpenC3 target to associate with the microservice. For standard OpenC3 microservices such as decom_microservice this causes the target configuration to get loaded into the container for the microservice."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Target Name"}),(0,s.jsx)(r.td,{children:"OpenC3 target to associate with the microservice"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"MICROSERVICE EXAMPLE openc3-example\n TARGET_NAME EXAMPLE\n"})}),"\n",(0,s.jsx)(r.h3,{id:"cmd-1",children:"CMD"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Command line to execute to run the microservice."})}),"\n",(0,s.jsx)(r.p,{children:"Command line to execute to run the microservice."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Args"}),(0,s.jsx)(r.td,{children:"One or more arguments to exec to run the microservice."}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.p,{children:"Ruby Example:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"MICROSERVICE EXAMPLE openc3-example\n CMD ruby example_target.rb\n"})}),"\n",(0,s.jsx)(r.p,{children:"Python Example:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-python",children:"MICROSERVICE EXAMPLE openc3-example\n CMD python example_target.py\n"})}),"\n",(0,s.jsx)(r.h3,{id:"option-1",children:"OPTION"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Pass an option to the microservice"})}),"\n",(0,s.jsx)(r.p,{children:"Generic key/value(s) options to pass to the microservice. These take the form of KEYWORD/PARAMS like a line in a OpenC3 configuration file. Multiple OPTION keywords can be used to pass multiple options to the microservice."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Option Name"}),(0,s.jsx)(r.td,{children:"Name of the option"}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Option Value(s)"}),(0,s.jsx)(r.td,{children:"One or more values to associate with the option"}),(0,s.jsx)(r.td,{children:"True"})]})]})]}),"\n",(0,s.jsx)(r.h3,{id:"container-1",children:"CONTAINER"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Docker Container"})}),"\n",(0,s.jsx)(r.p,{children:"Container to execute and run the microservice in. Only used in COSMOS Enterprise Edition."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Args"}),(0,s.jsx)(r.td,{children:"Name of the container"}),(0,s.jsx)(r.td,{children:"False"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"secret-1",children:"SECRET"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.3.0)"}),(0,s.jsx)(r.strong,{children:"Define a secret needed by this microservice"})]}),"\n",(0,s.jsxs)(r.p,{children:["Defines a secret for this microservice. For more information see ",(0,s.jsx)(r.a,{href:"/docs/tools/admin#secrets",children:"Admin Secrets"}),"."]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Type"}),(0,s.jsx)(r.td,{children:"ENV or FILE. ENV will mount the secret into an environment variable. FILE mounts the secret into a file."}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Secret Name"}),(0,s.jsxs)(r.td,{children:["The name of the secret to retrieve from the Admin / Secrets tab. For more information see ",(0,s.jsx)(r.a,{href:"/docs/tools/admin#secrets",children:"Admin Secrets"}),"."]}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Environment Variable or File Path"}),(0,s.jsx)(r.td,{children:"Environment variable name or file path to store secret"}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Secret Store Name"}),(0,s.jsx)(r.td,{children:"Name of the secret store for stores with multipart keys"}),(0,s.jsx)(r.td,{children:"False"})]})]})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:'SECRET ENV USERNAME ENV_USERNAME\nSECRET FILE KEY "/tmp/DATA/cert"\n'})}),"\n",(0,s.jsx)(r.h3,{id:"route_prefix-1",children:"ROUTE_PREFIX"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.5.0)"}),(0,s.jsx)(r.strong,{children:"Prefix of route"})]}),"\n",(0,s.jsx)(r.p,{children:"Prefix of route to the microservice to expose externally with Traefik"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Route Prefix"}),(0,s.jsx)(r.td,{children:"Route prefix. Must be unique across all scopes. Something like /myprefix"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"MICROSERVICE CFDP CFDP\n ROUTE_PREFIX /cfdp\n"})}),"\n",(0,s.jsx)(r.h3,{id:"disable_erb-1",children:"DISABLE_ERB"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.12.0)"}),(0,s.jsx)(r.strong,{children:"Disable ERB processing"})]}),"\n",(0,s.jsx)(r.p,{children:"Disable ERB processing for the entire microservice or a set of regular expressions over its filenames"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Regex"}),(0,s.jsx)(r.td,{children:"Regex to match against filenames. If match, then no ERB processing"}),(0,s.jsx)(r.td,{children:"False"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"shard-2",children:"SHARD"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 6.0.0)"}),(0,s.jsx)(r.strong,{children:"Operator shard to run target microservices on"})]}),"\n",(0,s.jsx)(r.p,{children:"Operator Shard. Only used if running multiple operator containers typically in Kubernetes"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Shard"}),(0,s.jsx)(r.td,{children:"Shard number starting from 0"}),(0,s.jsx)(r.td,{children:"False"})]})})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"SHARD 0\n"})}),"\n",(0,s.jsx)(r.h3,{id:"stopped",children:"STOPPED"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 6.2.0)"}),(0,s.jsx)(r.strong,{children:"Initially creates the microservice in a stopped state (not enabled)"})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"STOPPED\n"})}),"\n",(0,s.jsx)(r.h2,{id:"tool-1",children:"TOOL"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Define a tool"})}),"\n",(0,s.jsx)(r.p,{children:"Defines a tool that the plugin adds to the OpenC3 system. Tools are web based applications that make use of the Single-SPA javascript library that allows them to by dynamically added to the running system as independent frontend microservices."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Tool Folder Name"}),(0,s.jsx)(r.td,{children:"The exact name of the tool folder in the plugin. ie. tools/ToolFolderName"}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Tool Name"}),(0,s.jsx)(r.td,{children:"Name of the tool that is displayed in the OpenC3 Navigation menu"}),(0,s.jsx)(r.td,{children:"True"})]})]})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"TOOL DEMO Demo\n"})}),"\n",(0,s.jsx)(r.h2,{id:"tool-modifiers",children:"TOOL Modifiers"}),"\n",(0,s.jsx)(r.p,{children:"The following keywords must follow a TOOL keyword."}),"\n",(0,s.jsx)(r.h3,{id:"url",children:"URL"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Url used to access the tool"})}),"\n",(0,s.jsx)(r.p,{children:'The relative url used to access the tool. Defaults to "/tools/ToolFolderName".'}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Url"}),(0,s.jsx)(r.td,{children:"The url. If not given defaults to tools/ToolFolderName. Generally should not be given unless linking to external tools."}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"inline_url",children:"INLINE_URL"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Internal url to load a tool"})}),"\n",(0,s.jsx)(r.p,{children:'The url of the javascript file used to load the tool into single-SPA. Defaults to "main.js".'}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Url"}),(0,s.jsx)(r.td,{children:"The inline url. If not given defaults to main.js. Generally should not be given unless using a non-standard filename."}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"window",children:"WINDOW"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"How to display the tool when navigated to"})}),"\n",(0,s.jsx)(r.p,{children:"The window mode used to display the tool. INLINE opens the tool internally without refreshing the page using the Single-SPA framework. IFRAME opens external tools in an Iframe within OpenC3. NEW opens the tool in a new TAB."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Window Mode"}),(0,s.jsxs)(r.td,{children:["Tool display mode",(0,s.jsx)("br",{}),(0,s.jsx)("br",{}),"Valid Values: ",(0,s.jsx)("span",{class:"values",children:"INLINE, IFRAME, NEW"})]}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"icon",children:"ICON"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Set tool icon"})}),"\n",(0,s.jsx)(r.p,{children:"Icon shown next to the tool name in the OpenC3 navigation menu."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Icon Name"}),(0,s.jsxs)(r.td,{children:["Icon to display next to the tool name. Icons come from Font Awesome, Material Design (",(0,s.jsx)(r.a,{href:"https://materialdesignicons.com/",children:"https://materialdesignicons.com/"}),"), and Astro."]}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"category",children:"CATEGORY"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Category for the tool"})}),"\n",(0,s.jsx)(r.p,{children:"Associates the tool with a category which becomes a submenu in the Navigation menu."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Category Name"}),(0,s.jsx)(r.td,{children:"Category to associate the tool with"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"shown",children:"SHOWN"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Show the tool or not"})}),"\n",(0,s.jsx)(r.p,{children:"Whether or not the tool is shown in the Navigation menu. Should generally be true, except for the openc3 base tool."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Shown"}),(0,s.jsxs)(r.td,{children:["Whether or not the tool is shown. TRUE or FALSE",(0,s.jsx)("br",{}),(0,s.jsx)("br",{}),"Valid Values: ",(0,s.jsx)("span",{class:"values",children:"true, false"})]}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"position",children:"POSITION"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.0.8)"}),(0,s.jsx)(r.strong,{children:"Position of the tool in the nav bar"})]}),"\n",(0,s.jsx)(r.p,{children:"Position of the tool starting at 2 (1 is reserved for Admin Console). Tools without a position are appended to the end as they are installed. All COSMOS open source tools have consecutive integer values for position."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Position"}),(0,s.jsx)(r.td,{children:"Numerical position"}),(0,s.jsx)(r.td,{children:"True"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"disable_erb-2",children:"DISABLE_ERB"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.12.0)"}),(0,s.jsx)(r.strong,{children:"Disable ERB processing"})]}),"\n",(0,s.jsx)(r.p,{children:"Disable ERB processing for the entire tool or a set of regular expressions over its filenames"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Regex"}),(0,s.jsx)(r.td,{children:"Regex to match against filenames. If match, then no ERB processing"}),(0,s.jsx)(r.td,{children:"False"})]})})]}),"\n",(0,s.jsx)(r.h3,{id:"import_map_item",children:"IMPORT_MAP_ITEM"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 6.0.0)"}),(0,s.jsx)(r.strong,{children:"Add an item to the import map"})]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"key"}),(0,s.jsx)(r.td,{children:"Import Map Key"}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"value"}),(0,s.jsx)(r.td,{children:"Import Map Value"}),(0,s.jsx)(r.td,{children:"True"})]})]})]}),"\n",(0,s.jsx)(r.h2,{id:"widget",children:"WIDGET"}),"\n",(0,s.jsx)(r.p,{children:(0,s.jsx)(r.strong,{children:"Define a custom widget"})}),"\n",(0,s.jsx)(r.p,{children:"Defines a custom widget that can be used in Telemetry Viewer screens."}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Widget Name"}),(0,s.jsxs)(r.td,{children:["The name of the widget will be used to build a path to the widget implementation. For example, ",(0,s.jsx)(r.code,{children:"WIDGET HELLOWORLD"})," will find the as-built file tools/widgets/HelloworldWidget/HelloworldWidget.umd.min.js. See the ",(0,s.jsx)(r.a,{href:"/tools/staticdocs/docs/guides/custom-widgets",children:"Custom Widgets"})," guide for more details."]}),(0,s.jsx)(r.td,{children:"True"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Label"}),(0,s.jsx)(r.td,{children:"The label for the widget that will appear in the Data Viewer component drop down"}),(0,s.jsx)(r.td,{children:"False"})]})]})]}),"\n",(0,s.jsx)(r.p,{children:"Example Usage:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ruby",children:"WIDGET HELLOWORLD\n"})}),"\n",(0,s.jsx)(r.h2,{id:"widget-modifiers",children:"WIDGET Modifiers"}),"\n",(0,s.jsx)(r.p,{children:"The following keywords must follow a WIDGET keyword."}),"\n",(0,s.jsx)(r.h3,{id:"disable_erb-3",children:"DISABLE_ERB"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)("div",{class:"right",children:"(Since 5.12.0)"}),(0,s.jsx)(r.strong,{children:"Disable ERB processing"})]}),"\n",(0,s.jsx)(r.p,{children:"Disable ERB processing for the entire widget or a set of regular expressions over its filenames"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Parameter"}),(0,s.jsx)(r.th,{children:"Description"}),(0,s.jsx)(r.th,{children:"Required"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Regex"}),(0,s.jsx)(r.td,{children:"Regex to match against filenames. If match, then no ERB processing"}),(0,s.jsx)(r.td,{children:"False"})]})})]})]})}function o(e={}){let{wrapper:r}={...(0,t.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},2840:function(e,r,n){n.d(r,{Z:function(){return d},a:function(){return l}});var i=n(2784);let s={},t=i.createContext(s);function l(e){let r=i.useContext(t);return i.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function d(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),i.createElement(t.Provider,{value:r},e.children)}}}]);
|
@@ -1 +0,0 @@
|
|
1
|
-
"use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["9880"],{8198:function(e,t,n){n.r(t),n.d(t,{default:()=>h,frontMatter:()=>o,metadata:()=>i,assets:()=>a,toc:()=>l,contentTitle:()=>s});var i=JSON.parse('{"id":"configuration/ssl-tls","title":"SSL-TLS","description":"How to configure SSL and TLS","source":"@site/docs/configuration/ssl-tls.md","sourceDirName":"configuration","slug":"/configuration/ssl-tls","permalink":"/tools/staticdocs/docs/configuration/ssl-tls","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/configuration/ssl-tls.md","tags":[],"version":"current","sidebarPosition":11,"frontMatter":{"sidebar_position":11,"title":"SSL-TLS","description":"How to configure SSL and TLS","sidebar_custom_props":{"myEmoji":"\uD83D\uDD10"}},"sidebar":"defaultSidebar","previous":{"title":"Screens","permalink":"/tools/staticdocs/docs/configuration/telemetry-screens"},"next":{"title":"Tools","permalink":"/tools/staticdocs/docs/tools"}}'),r=n("2322"),c=n("2840");let o={sidebar_position:11,title:"SSL-TLS",description:"How to configure SSL and TLS",sidebar_custom_props:{myEmoji:"\uD83D\uDD10"}},s=void 0,a={},l=[{value:"Generate the certificate",id:"generate-the-certificate",level:3},{value:"Updating the openc3-traefik Dockerfile",id:"updating-the-openc3-traefik-dockerfile",level:3},{value:"Updating the Traefik config",id:"updating-the-traefik-config",level:3},{value:"Update docker-compose.yaml",id:"update-docker-composeyaml",level:3},{value:"Let's Encrypt",id:"lets-encrypt",level:2},{value:"KEY",id:"key",level:4},{value:"CRT",id:"crt",level:4},{value:"CRT/KEY Bundle",id:"crtkey-bundle",level:4},{value:"cert.pem",id:"certpem",level:4},{value:"chain.pem",id:"chainpem",level:4},{value:"Checking certs",id:"checking-certs",level:3},{value:"Extracting the certificate and keys from a .pfx file",id:"extracting-the-certificate-and-keys-from-a-pfx-file",level:2},{value:"Extract .crt and .key files from .pfx file",id:"extract-crt-and-key-files-from-pfx-file",level:3},{value:"Convert .pfx file to .pem format",id:"convert-pfx-file-to-pem-format",level:3},{value:"TLS1.2 INADEQUATE_SECURITY Errors",id:"tls12-inadequate_security-errors",level:2}];function d(e){let t={a:"a",blockquote:"blockquote",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,c.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(t.p,{children:["COSMOS 5 is a container based service which does not use SSL/TLS out of the box. This guide will help you configure SSL and TLS. Learn more at the Traefik ",(0,r.jsx)(t.a,{href:"https://doc.traefik.io/traefik/routing/entrypoints/#tls",children:"docs"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"generate-the-certificate",children:"Generate the certificate"}),"\n",(0,r.jsxs)(t.blockquote,{children:["\n",(0,r.jsx)(t.p,{children:"Note: Self-signed certificates are considered insecure for the Internet. Firefox will treat the site as having an invalid certificate, while Chrome will act as if the connection was plain HTTP."}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"To create a new Self-Signed SSL Certificate, use the openssl req command (run on linux from the cosmos-project root):"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"openssl req -newkey rsa:4096 \\\n -x509 \\\n -sha256 \\\n -days 3650 \\\n -nodes \\\n -out ./openc3-traefik/cert.crt \\\n -keyout ./openc3-traefik/cert.key\n\nCountry Name (2 letter code) [XX]:.\nState or Province Name (full name) []:.\nLocality Name (eg, city) [Default City]:.\nOrganization Name (eg, company) [Default Company Ltd]:.\nOrganizational Unit Name (eg, section) []:.\nCommon Name (eg, your name or your server hostname) []: \x3c!-- UPDATE WITH YOUR HOSTNAME HERE --\x3e\nEmail Address []:\n"})}),"\n",(0,r.jsx)(t.p,{children:"Let's breakdown the command and understand what each option means:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"newkey rsa:4096"})," - Creates a new certificate request and 4096 bit RSA key. The default one is 2048 bits."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"x509"})," - Creates a X.509 Certificate."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"sha256"})," - Use 265-bit SHA (Secure Hash Algorithm)."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"days 3650"})," - The number of days to certify the certificate for. 3650 is ten years. You can use any positive integer."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"nodes"})," - Creates a key without a passphrase."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"out ./openc3-traefik/cert.crt"})," - Specifies the filename to write the newly created certificate to. You can specify any file name."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"keyout ./openc3-traefik/cert.key"})," - Specifies the filename to write the newly created private key to. You can specify any file name."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["For more information about the ",(0,r.jsx)(t.code,{children:"openssl req"})," command options, visit the ",(0,r.jsx)(t.a,{href:"https://www.openssl.org/docs/man1.0.2/man1/openssl-req.html",children:"OpenSSL req documentation page"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"updating-the-openc3-traefik-dockerfile",children:"Updating the openc3-traefik Dockerfile"}),"\n",(0,r.jsx)(t.p,{children:"Add the new cert to the traefik Docker container."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-diff",children:"--- a/openc3-traefik/Dockerfile\n+++ b/openc3-traefik/Dockerfile\n@@ -1,3 +1,4 @@\n FROM traefik:2.4\n COPY ./traefik.yaml /etc/traefik/traefik.yaml\n+COPY ./cert.crt ./cert.key /etc/certs/\n EXPOSE 80\n"})}),"\n",(0,r.jsx)(t.h3,{id:"updating-the-traefik-config",children:"Updating the Traefik config"}),"\n",(0,r.jsx)(t.p,{children:"Configure Traefik to use the new cert file."}),"\n",(0,r.jsx)(t.p,{children:"openc3-traefik/traefik.yaml"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-diff",children:'--- a/openc3-traefik/traefik.yaml\n+++ b/openc3-traefik/traefik.yaml\n@@ -3,6 +3,17 @@\n+tls:\n+ certificates:\n+ - certFile: "/etc/certs/cert.crt"\n+ keyFile: "/etc/certs/cert.key"\n# Listen for everything coming in on the standard HTTP port\nentrypoints:\n web:\n address: ":2900"\n+ http:\n+ redirections:\n+ entryPoint:\n+ to: websecure\n+ scheme: https\n+ websecure:\n+ address: ":2943"\n+ http:\n+ tls:\n+ domains:\n+ - main: "\x3c!-- UPDATE WITH YOUR HOSTNAME HERE --\x3e"\n'})}),"\n",(0,r.jsx)(t.h3,{id:"update-docker-composeyaml",children:"Update docker-compose.yaml"}),"\n",(0,r.jsx)(t.p,{children:"Update traefik to use secure port 443 instead of port 80."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-diff",children:'--- a/compose.yaml\n+++ b/compose.yaml\n services:\n openc3-minio:\n@@ -70,7 +70,7 @@ services:\n openc3-traefik:\n image: "ballaerospace/openc3-traefik:${OPENC3_TAG}"\n ports:\n- - "80:2900"\n+ - "443:2943"\n restart: "unless-stopped"\n depends_on:\n'})}),"\n",(0,r.jsxs)(t.p,{children:["Now you can run ",(0,r.jsx)(t.code,{children:"./openc3.sh start"})," to rebuild the Traefik container and it should include your new cert file."]}),"\n",(0,r.jsx)(t.h2,{id:"lets-encrypt",children:"Let's Encrypt"}),"\n",(0,r.jsx)(t.h4,{id:"key",children:"KEY"}),"\n",(0,r.jsx)(t.p,{children:'privkey.pem is the "key" file'}),"\n",(0,r.jsx)(t.p,{children:"Sometimes it is named as cert.key or example.com.key."}),"\n",(0,r.jsx)(t.h4,{id:"crt",children:"CRT"}),"\n",(0,r.jsx)(t.p,{children:'fullchain.pem is your "crt" file.'}),"\n",(0,r.jsx)(t.p,{children:"Sometimes it is named as example.com.crt."}),"\n",(0,r.jsx)(t.h4,{id:"crtkey-bundle",children:"CRT/KEY Bundle"}),"\n",(0,r.jsx)(t.p,{children:"bundle.pem would be made like so: cat fullchain.pem privkey.pem > bundle.pem"}),"\n",(0,r.jsx)(t.p,{children:"HAProxy is the only server that I know of that uses bundle.pem."}),"\n",(0,r.jsx)(t.h4,{id:"certpem",children:"cert.pem"}),"\n",(0,r.jsx)(t.p,{children:"cert.pem contains ONLY your certificate, which can only be used by itself if the browser already has the certificate which signed it, which may work in testing (which makes it seem like it may be the right file), but will actually fail for many of your users in production with a security error of untrusted certificate."}),"\n",(0,r.jsx)(t.p,{children:"However, you don't generally use the cert.pem by itself. It's almost always coupled with chain.pem as fullchain.pem."}),"\n",(0,r.jsx)(t.h4,{id:"chainpem",children:"chain.pem"}),"\n",(0,r.jsx)(t.p,{children:"chain.pem is the intermediary signed authority, signed by the root authority - which is what all browsers are guaranteed to have in their pre-built cache."}),"\n",(0,r.jsx)(t.h3,{id:"checking-certs",children:"Checking certs"}),"\n",(0,r.jsx)(t.p,{children:"You can inspect the cert like so:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"openssl x509 -in cert.pem -text -noout\n"})}),"\n",(0,r.jsx)(t.h2,{id:"extracting-the-certificate-and-keys-from-a-pfx-file",children:"Extracting the certificate and keys from a .pfx file"}),"\n",(0,r.jsx)(t.p,{children:"The .pfx file, which is in a PKCS#12 format, contains the SSL certificate (public keys) and the corresponding private keys. You might have to import the certificate and private keys separately in an unencrypted plain text format to use it on another system. This topic provides instructions on how to convert the .pfx file to .crt and .key files."}),"\n",(0,r.jsx)(t.h3,{id:"extract-crt-and-key-files-from-pfx-file",children:"Extract .crt and .key files from .pfx file"}),"\n",(0,r.jsxs)(t.blockquote,{children:["\n",(0,r.jsx)(t.p,{children:"PREREQUISITE: Ensure OpenSSL is installed in the server that contains the SSL certificate."}),"\n"]}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Start OpenSSL from the OpenSSL\\bin folder."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Open the command prompt and go to the folder that contains your .pfx file."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Run the following command to extract the private key:"}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"openssl pkcs12 -in [yourfile.pfx] -nocerts -out [drlive.key]\n"})}),"\n",(0,r.jsx)(t.p,{children:"You will be prompted to type the import password. Type the password that you used to protect your keypair when you created the .pfx file. You will be prompted again to provide a new password to protect the .key file that you are creating. Store the password to your key file in a secure place to avoid misuse."}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Run the following command to extract the certificate:"}),"\n"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"openssl pkcs12 -in [yourfile.pfx] -clcerts -nokeys -out [drlive.crt]\n"})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Run the following command to decrypt the private key:"}),"\n"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"openssl rsa -in [drlive.key] -out [drlive-decrypted.key]\n"})}),"\n",(0,r.jsx)(t.p,{children:"Type the password that you created to protect the private key file in the previous step.\nThe .crt file and the decrypted and encrypted .key files are available in the path, where you started OpenSSL."}),"\n",(0,r.jsx)(t.h3,{id:"convert-pfx-file-to-pem-format",children:"Convert .pfx file to .pem format"}),"\n",(0,r.jsx)(t.p,{children:"There might be instances where you might have to convert the .pfx file into .pem format. Run the following command to convert it into PEM format."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"openssl rsa -in [keyfile-encrypted.key] -outform PEM -out [keyfile-encrypted-pem.key]\n"})}),"\n",(0,r.jsx)(t.h2,{id:"tls12-inadequate_security-errors",children:"TLS1.2 INADEQUATE_SECURITY Errors"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"https://doc.traefik.io/traefik/https/tls/#cipher-suites",children:"https://doc.traefik.io/traefik/https/tls/#cipher-suites"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"https://pkg.go.dev/crypto/tls#pkg-constants",children:"https://pkg.go.dev/crypto/tls#pkg-constants"})}),"\n"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-yaml",children:"tls:\n options:\n default:\n cipherSuites:\n - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\n - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\n - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\n - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256\n - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256\n"})})]})}function h(e={}){let{wrapper:t}={...(0,c.a)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},2840:function(e,t,n){n.d(t,{Z:function(){return s},a:function(){return o}});var i=n(2784);let r={},c=i.createContext(r);function o(e){let t=i.useContext(c);return i.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(c.Provider,{value:t},e.children)}}}]);
|