Commit Graph
85 Commits
Author SHA1 Message Date
Hornwitser 0a6e26bb2d Add connection events for control connections
Add hooks for plugins to be able to handle connection state changes for
control connections on the master server and in the web interface.
2021-03-20 03:35:05 +01:00
Hornwitser 48786f1e59 Fix --dev-plugin breaking after bd53339
The automatic determination of the public path for plugins works
correctly when they are build for production and loaded from their
respective paths.  But when the dev middelware compiles it, it doesn't
know the correct path to host it at withouth the publicPath being set.

Fix by setting publicPath explicitly when compiling with the dev
middleware.
2021-03-20 03:35:05 +01:00
Hornwitser f9048d7027 Set UI color on chrome mobile 2021-03-18 23:05:59 +01:00
Hornwitser 6458810571 Add name to account model
Add the name of the account that's connected to the control link on the
web interface via an additional property on the ready payload for the
control link.
2021-03-18 23:05:47 +01:00
Hornwitser 9542246414 Use a diff and author friendly markdown formatting (#370)
Simplify the the way markdown files are formatted to make them easier to
author without editors that do auto line breaking, and make the diffs
from them simpler to read.
2021-03-17 21:30:51 +01:00
Hornwitser a2d56d4a8d Fix crash on continuing an active connection (#369)
Fix ServerConnector reaching an invalid state if a continue operation is
performed on an active connection.  The continue would cause the
connection established logic to be runned before the connection lost
logic of the pervious connection is perfomed, resulting in a leaked
heartbeat interval and the connection lost logic being performed on the
new connection instead of the old.  Prevent this by closing both the new
and the old connection in this case.
2021-03-17 20:20:12 +01:00
Hornwitser 72d0994ca6 Add Player Auth plugin (#368)
Add authentication plugin that does a simple challenge response protocol
to verify that the player trying to log in is who they claim to be.  The
process goes as follows:

1. A player code is generated for a player that wants to log in and is
   displayed in-game.
2. The player code is input into the web interface and the master
   generates a verification code as a challenge back along with a token.
3. The player inputs the verification code in-game and is logged in to
   the web interface in doing so.

To do the actual login the web interface polls a verify endpoint every 2
seconds until the code has either been verified or expired.  The
challenge comes from being unable to control the verification code and
having to input it as a player logging into one of the servers in order
to login.

Some additional steps are taken in order to increase the difficulty for
an attacker to subvert the challenge:

- The login process must be started from in-game.
- Generated codes are only valid for a limited timespan which is
  configurable and 2 minutes by default.
- The verification code comes with a token that only works with one
  player code and verification code combo and must be provided to pass
  validation.
2021-03-17 18:48:22 +01:00
Hornwitser 941639666d Use auto publicPath deduction
Change to "auto" as the publicPath to have webpack deduce the correct
path at runtime.  This fixes an issue with plugins being unable to be
loaded due to trying to load bundles from the wrong path when the web
interface is hosted under a proxied sub-path.
2021-03-17 18:00:12 +01:00
Hornwitser bd53339532 Fix web root path confusion
Remove basename in favor of making webRoot absolute.  The distinction
between the two were supposed to be that basename was absolute and did
not have a trailing slash while webRoot was relative and had a traling
slash.  This was not how it ended up working in the code, which lead to
double forward slashes in requests sent out when webRoot was not equal
to './'.
2021-03-17 17:59:35 +01:00
Hornwitser 579f6421e4 Export web_ui as a single module
Due to the way the imports and exports works with module fedderation
each require path needs it's own shared module in the plugin.  To avoid
having to specify every possible import in the module federation plugin
config, export all useful components to plugins in the browser
entrypoint for web_ui.

Note that for some reason the module wouldn't exist for import by
plugins unless some part of the build imported it.  Which is the reason
for the master index.jsx to import bootstrap via it.
2021-03-13 21:01:53 +01:00
Hornwitser a904a8fb9d Add hit counter for HTTP requests
Add a complementary total hit counter for all HTTP requests.  The
endpointHitCounter doesn't cover all endpoints and fixing it to cover
all endpoints without making it possible for it to create an infinite
number of time seriers is not straight forward.
2021-03-13 21:01:53 +01:00
Hornwitser a8e1971483 Fix data loss on bad name passed --dev-plugin
If data from the database is not loaded but a shutdown is triggered then
the master server will overwrite the database with empty data, causing
unexpected data loss.  This occurs for example when the --dev-plugin
option throws.

Fix by setting the database entries to null before they are loaded so
that should an attempt be made to save them without having been loaded
first it will throw an error instead.
2021-03-13 21:01:53 +01:00
Hornwitser 78ce6fc382 Move /plugin/name/ to /plugins/name/
The web files for plugins were hosted at /plugin/plugin_name/ while the
view page for a plugin is hosted at /plugins/plugin_name/view.  Reduce
confusion by making both urls use the plural version.
2021-03-13 21:01:53 +01:00
Hornwitser 71804df3e0 Add --dev-plugin to compile plugins on the fly
Add hidden development option to run the webpack compiller for the given
plugin(s) similar to the --dev option for the built-in web interface.

This requires publicPath to be set in the webpack config and an updated
version of webpack-dev-middleware to function correctly.
2021-03-13 21:01:53 +01:00
Hornwitser 5ce3fb6cc6 Add loading of web plugins in interface
Add separate BaseWebPlugin class which plugins can extend and expose
through a webEntrypoint in a similar fasion to the existing master,
instance and control entrypoints.

To simplify the logic for the rest of the web interface code the plugins
context is changed to be a mapping of loaded WebPlugin instances.  This
in turn means the plugins and plugin view pages fetches the plugin list
upon load in order to show plugins that failed to load (which
incidentally also gives them an up to date list).
2021-03-13 21:01:53 +01:00
Hornwitser e1c7d35ce4 Fix plugin shutdown not called on bad startup
During startup the plugins are loaded one by one and init is called for
each of them.  But due to the already loaded plugins being discarded if
one of the plugins throw an error an unclean shutdown that might hang
on timers started by plugins occurs.  This leads to the master server
starting up, printing an error, displaying the shutdown sequence and
then hang forever.

Fix by storing the plugins loaded into masterPlugins as they are loaded
instead only after all of them have been loaded.
2021-03-07 15:18:39 +01:00
Hornwitser b814d8a400 Share each individual lib import webpack config
The module sharing in Webpack works on a per import basis and therefore
doesn't trigger when the value in the config is @clusterio/lib while the
module imported is @clusterio/lib/config.  This in turn caused a copy of
lib to be bundled with each plugin.  Fix by making sure each lib import
is shared and specified in the configs.
2021-03-07 15:12:23 +01:00
Hornwitser 415f574e2d Remove obsolete "updater" code
Remove commented out reference to an updater module which was never
completed in master.js.
2021-03-07 14:55:57 +01:00
Hornwitser 63f76ce87a Rename enabled to load_plugin
Rename the config and status indicating whether to load a plugin or not
from "Enabled" to "Load Plugin".  The latter better describes what it
does, and unlike the former doesn't imply plugins can be enabled or
disabled on the fly.
2021-03-07 14:53:45 +01:00
Hornwitser 85a984734b Fix node-forge dependency
The removal of the automatic TLS certificate generation removed the use
of node-forge in the master server, while the addition of the HttpCloser
added it as dependency of the tests.  Fix node-forge dependency being
listed in lib and master instead of as a dev dependency in package.json.
2021-03-06 18:38:30 +01:00
Hornwitser 6c9d3d8893 Add Plugins page to web interface
Add page listing the plugins installed on the master along with a
detailed page for each plugin with fields from their package.json.
Failure to load the module and version missmatch is also reported.
This adds ./packages.json as required part of the webpack module.
2021-03-01 15:03:25 +01:00
Hornwitser 6a29cd9715 Resolve webpack modules from web_ui
Remove the need for installing babel and the webpack loaders used in the
webpack.common.js file separately by resolving them from the web_ui
package.  This allows future changes to done to the modules used without
having to update them in each plugin that uses the web_ui common config.
2021-03-01 14:59:59 +01:00
Hornwitser 9869d92ead v2.0.0-alpha.4 2021-02-26 15:52:18 +01:00
Hornwitser bec30c9927 Add remote editing of master config
Add commands and web UI for editing the master configuration remotely.
2021-02-24 22:16:03 +01:00
Hornwitser 2c74a67738 Add location access control to config class
Add a per field access parameter to the config class which specifies
which of master, slave and control can access the given field.  A
location is added to the config class to specify which party owns it and
fields which do not have an access parameter are not present in the
config and will throw if attempted to be read from or writen to.

The serialize, load, update, get, set and setProp are ammended with a
location parameter which specifiy where the data is from or destined to
and the access checks are performed to ensure remote access to the
config is still limited by the access parameter of field.

With this system in place the master config can be shared with control
and slave connections without compromising secrets that should stay
private.  This is primarily the master authentication secret, but other
plugins may define secrets it does not want to have shared with slave
and/or control connections.
2021-02-24 15:46:19 +01:00
Hornwitser 1de8b76303 Emit resume instead of connect on resumed connections
Raise "resume" instead of "connect" when a connection is re-established
after a connection drop.  This prevents logic meant to resynchronize
state after a full reconnection from being invoked whenever the
connection was temporarily dropped.
2021-02-19 14:28:19 +01:00
Hornwitser f8153bd784 Remove redundant parameter from attachPluginMessages
Remove the pluginInfo parameter from lib/plugin attachPluginMessages as
the plugin info object is available in the `.info` property of the
plugin.  While a plugin instance doesn't exist for the slave side and
was the reason for these to be separate arguments, I expect slave
plugins to be implemented eventually.
2021-02-17 21:21:18 +01:00
Hornwitser b7c7e79a86 Move distributed static/ folder to dist/web/
Move the target folder for the built web interface to dist/web/ instead
of static/.  This better follows the norm for npm packages to include
built files in the dist/ folder and also allows putting other built
files into that folder in the future.
2021-02-17 21:21:18 +01:00
Hornwitser 9660fa0801 Handle SIGHUP gracefully
Invoke shutdown instead of exiting immediately when SIGHUP is received,
and do the same on both slave and master for signals received.
2021-02-17 17:49:54 +01:00
Hornwitser 4ca092f351 Prevent shutdown running more than once
Exit immediately if shutdown has already been called.  This is due to
the possibility of it being called multiple times from combinations of
signals and fatal errors.
2021-02-17 17:48:05 +01:00
Hornwitser 99fa6b4b12 Set blocking on logging before process.exit
On windows the terminal output is asynchronous by default which leads to
log lines being lost if text is written to stdout before calling
process.exit.  Fix by using setBlocking before doing the log call.
2021-02-17 17:45:43 +01:00
Matthew Jensen 40bd3edb32 Added TERM signal handler 2021-02-03 10:00:40 +11:00
Hornwitser b84c5b4293 Add common settings for Factorio servers
Add settings of interest to server administrators that appear in
server-settings.json to the factorio.settings config.  This makes it
easier to see which settings can be set there.
2021-01-18 08:17:14 +01:00
Hornwitser 1b901f5d1c Fix the remaning linter warnings (#353)
Refactor the code base to remove all of the remaining warnings from
ESLint and convert them into errors.
2021-01-05 22:28:08 +01:00
Hornwitser 3592ff3269 Remove automatic creation of TLS certificate
The automatic creation of a self-signed certificate while nice presents
several problems.  To make connections not reject the self-signed
certificate the validation of TLS certificates are wholesale disabled,
decreasing the security even when properly set up and trusted
certificates are used.

To make the created self-signed certificate pass validation it is
necessary for it to list the host names it's valid for and to copy it to
each machine that intends to connect to the server.  These two steps
complicate automating the process in a reliable way and will likely lead
to confused users seeking to disable TLS certificate validation as the
easy way out to problems.

For these reasons, remove the automating creation of a broke self-signed
certificate, fix validation of certificates and document how to set up
TLS properly.  This makes HTTPS recommended when accessing over the
internet, but still something which must be explicitly configured.
2021-01-04 08:22:05 +01:00
Hornwitser 16525ae07c Add graceful closure of HTTP connections
When closing down the HTTP and HTTPS servers existing connections are
not closed by Node.js, and may live on forever if they are actively in
use.  A common case where this happens is if Prometheus is set up with a
short interval for collections.

To close down the active connections they need to be tracked and closed
when the server is closed, add the HttpCloser class which encapsulates
the tracking and closure process behind a simple interface and use this
to close down the HTTP and HTTPS server on the master.
2020-12-28 07:05:04 +01:00
Hornwitser 6eef4bd300 Make metrics gathering timeout configurable
When reducing the collection interval in Prometheus it may be necessary
to to reduce the metrics gathering timeout to ensure it's less than the
interval.  Add config options to adjust the timeouts used for metrics
gathering so that these can be set accordingly.
2020-12-28 07:03:32 +01:00
tovernaar123 35cb9f8698 Add bind_address option (#349)
Add option to set the IP address the master server binds its HTTP and
HTTPS ports to.
2020-12-28 03:40:28 +01:00
Hornwitser b3e518d570 v2.0.0-alpha.3 2020-12-14 07:11:34 +01:00
Hornwitser 450e27e001 Add metric mapping slave and instance id to name
Add exported metrics that map instance id and slave id to their
respective names.  This allows getting the instance name of a metric by
doing a left join using query of the form 'metric * on(instance_id)
group_left(instance_name) clusterio_master_instance_mapping'.
2020-12-07 17:22:17 +01:00
Hornwitser 93752e671e Fix plugin errors show incorrect error stack
Fix master server showing the stack of the PluginError instance on
startup instead of the original error that the plugin threw.
2020-11-30 02:49:06 +01:00
Hornwitser 1c8a2fef32 Add log inspection commands
Add log query and log follow commands which allows inspection of the
combined cluster log.  Past entries can be queried via the new queryLog
request.  The log is stored into a single flat file for now, though the
performance of this may good enough.
2020-11-30 02:49:06 +01:00
Hornwitser 957983d8a5 Add logging system based on winston
Add winston based logger for master, slave, ctl, lib, and web_ui code.
Logging done from slaves and instances are sent to the master server and
tagged with the instance and/or slave it originated from.  This allows
for example error messages to propagate back to the source that iniated
the action.  The master server also stores the log to allow it to be
queried at a later point.  For slaves a copy of the slave's log is also
stored locally.
2020-11-27 17:51:07 +01:00
Hornwitser 8f176c969b Merge pull request #340 from Hornwitser/rcon-performance
Improvements from investigating RCON performance
2020-11-20 22:27:19 +01:00
Hornwitser e5e1851852 Add Histogram collector to prometheus client
Move common functionality between labeled collectors out of
ValueCollector and into a new LabeledCollector class, and use this as
the basis for implementing a Histogram collector.
2020-11-18 21:27:18 +01:00
justchen1369 c65494f093 change some occurrences of var 2020-11-17 23:53:35 -05:00
Hornwitser 9d2ac2b81f Rework instance assigment process
Under the current system there's no distinction made on the slave side
between instance config files that are present in the filesystem and
instances actually assigned to the slave.  Which could lead to problems
with determing if an instance is actually assigned to the slave.

Resolve this issue by separating discovered instances with assigned
instances.  Upon startup discovered instances are put into the
discoveredInstanceInfos mapping on the Slave object and all of these are
sent to the master server.  The master server in turn sends assignment
requests for all the instances which are assigned to the slave.  These
are put into the instanceInfos mapping of the Slave object which can
then be relied up to include only assigned instances.
2020-11-17 04:34:49 +01:00
Hornwitser b742291131 Add timeout to slave metric request
When the slave metrics request takes more than 10 seconds the response
to the /metrics endpoint ends up being discarded by Prometheus which
defaults to a timeout of 10 seconds.  Fix by ignoring slaves that take
longer than 8 seconds to respond to the metrics request.
2020-11-17 04:19:05 +01:00
Hornwitser 36865cfcf9 v2.0.0-alpha.2 2020-11-09 12:50:24 +01:00
Hornwitser 6a4875c5ec Add bootstrap generate-user-token command
Add command to generate a user token for connecting to the master server
web interface.  This servers as an alternative to generating a control
config for use with clusterioctl.
2020-11-08 18:27:24 +01:00