allow limited service control via the command interface

This commit is contained in:
Madpeter 2024-07-22 20:19:48 +01:00
parent c789e53910
commit 9987d7fcb1
18 changed files with 184 additions and 11 deletions

View file

@ -36,6 +36,7 @@ ENV basic_Username='' \
commands_TimeWindowSecs=35 \
commands_Enabled='true' \
commands_ObjectMasterOptout='false' \
commands_AllowServiceControl='false' \
datastore_AutoCleanAvatars='true' \
datastore_AvatarsCleanAfterMins=10 \
datastore_LocalChatHistoryLimit=120 \

View file

@ -0,0 +1,138 @@
using Newtonsoft.Json;
using OpenMetaverse;
using SecondBotEvents.Services;
using System.Collections.Generic;
using System.Linq;
namespace SecondBotEvents.Commands
{
[ClassInfo("Control services via commands (Requires the command enable service control flag be set to true)<br/><hr/> controlable services:<br/><hr/>" +
"BotClientService<br/>"+
"RLVService<br/>" +
"HttpService<br/>" +
"DiscordService<br/>" +
"InteractionService<br/>" +
"HomeboundService<br/>" +
"EventsService<br/>" +
"DialogService<br/>" +
"TriggerOnEventService" +
"RelayService")]
public class Services : CommandsAPI
{
public Services(EventsSecondBot setmaster) : base(setmaster)
{
}
protected List<string> controlable = new List<string> { "BotClientService","RLVService",
"HttpService",
"DiscordService",
"InteractionService",
"HomeboundService",
"EventsService",
"DialogService",
"TriggerOnEventService",
"RelayService"};
[About("Marks a service as enabled and starts it")]
[ReturnHints("ok")]
[ReturnHintsFailure("Unknown service")]
[ReturnHintsFailure("Unable to manage selected service")]
[ReturnHintsFailure("Service control is not enabled by config")]
public object EnableAndStartService(string servicename)
{
if(master.CommandsService.GetAllowServiceCommands() == false)
{
return Failure("Service control is not enabled by config");
}
if(controlable.Contains(servicename) == false)
{
return Failure("Unknown service");
}
BotServices service = master.GetService(servicename);
if (service == null)
{
return Failure("Unknown service");
}
service.enableAndStart();
return BasicReply("ok");
}
[About("stops a service if it is running")]
[ReturnHints("ok")]
[ReturnHintsFailure("Unknown service")]
[ReturnHintsFailure("Unable to manage selected service")]
[ReturnHintsFailure("Service control is not enabled by config")]
public object StopService(string servicename)
{
if (master.CommandsService.GetAllowServiceCommands() == false)
{
return Failure("Service control is not enabled by config");
}
if (controlable.Contains(servicename) == false)
{
return Failure("Unknown service");
}
BotServices service = master.GetService(servicename);
if (service == null)
{
return Failure("Unknown service");
}
service.Stop();
return BasicReply("ok");
}
[About("restarts a service if it is running")]
[ReturnHints("ok")]
[ReturnHintsFailure("Unknown service")]
[ReturnHintsFailure("Unable to manage selected service")]
[ReturnHintsFailure("Service control is not enabled by config")]
public object RestartService(string servicename)
{
if (master.CommandsService.GetAllowServiceCommands() == false)
{
return Failure("Service control is not enabled by config");
}
if (controlable.Contains(servicename) == false)
{
return Failure("Unknown service");
}
BotServices service = master.GetService(servicename);
if (service == null)
{
return Failure("Unknown service");
}
service.Restart();
return BasicReply("ok");
}
[About("Change or add a config value to a service")]
[ReturnHints("ok")]
[ReturnHintsFailure("Unknown service")]
[ReturnHintsFailure("Unable to manage selected service")]
[ReturnHintsFailure("Service control is not enabled by config")]
public object ChangeConfigValue(string servicename,string configname,string configvalue)
{
if (master.CommandsService.GetAllowServiceCommands() == false)
{
return Failure("Service control is not enabled by config");
}
if (controlable.Contains(servicename) == false)
{
return Failure("Unknown service");
}
BotServices service = master.GetService(servicename);
if (service == null)
{
return Failure("Unknown service");
}
service.changeConfig(configname, configvalue);
return BasicReply("ok");
}
}
}

View file

@ -20,9 +20,13 @@ namespace SecondBotEvents.Config
settings.Add("TimeWindowSecs");
settings.Add("Enabled");
settings.Add("ObjectMasterOptout");
settings.Add("AllowServiceControl");
settings.Add("HideStatusOutput");
}
public bool GetAllowServiceControl()
{
return ReadSettingAsBool("AllowServiceControl", false);
}
public bool GetEnabled()
{
return ReadSettingAsBool("Enabled", true);

View file

@ -23,6 +23,16 @@ namespace SecondBotEvents.Config
MakeSettings();
LoadSettings(fromENV, fromFolder);
}
public void updateKey(string key, string value)
{
if(mysettings.ContainsKey(key))
{
mysettings[key] = value;
return;
}
mysettings.Add(key, value);
}
public void setEnabled(bool enabled)
{
mysettings["Enabled"] = enabled.ToString();

View file

@ -164,6 +164,7 @@ namespace SecondBotEvents
RegisterService("DialogService");
RegisterService("CustomCommandsService");
RegisterService("TriggerOnEventService");
RegisterService("RelayService");
if (BotClient.IsLoaded() == false)
{
LogFormater.Info("Config is not loaded :(");

View file

@ -49,6 +49,11 @@ namespace SecondBotEvents.Services
LoadCommands();
}
public bool GetAllowServiceCommands()
{
return myConfig.GetAllowServiceControl();
}
protected void LoadCommands()
{
Dictionary<string, Type> commandmodules = http_commands_helper.getCommandModules();

View file

@ -11,7 +11,7 @@ namespace SecondBotEvents.Services
{
public class CustomCommandsService: BotServices
{
protected CustomCommandsConfig myConfig;
protected new CustomCommandsConfig myConfig;
protected bool botConnected = false;
protected Dictionary<string, CustomCommand> commands = new Dictionary<string, CustomCommand>();
public bool HasCommand(string C)

View file

@ -14,7 +14,7 @@ namespace SecondBotEvents.Services
{
public class DataStoreService : BotServices
{
protected DataStoreConfig myConfig;
protected new DataStoreConfig myConfig;
protected bool botConnected = false;
public DataStoreService(EventsSecondBot setMaster) : base(setMaster)
{

View file

@ -17,7 +17,7 @@ namespace SecondBotEvents.Services
public class DialogService : BotServices
{
protected bool botConnected = false;
protected DialogRelayConfig myConfig;
protected new DialogRelayConfig myConfig;
public DialogService(EventsSecondBot setMaster) : base(setMaster)
{
myConfig = new DialogRelayConfig(master.fromEnv, master.fromFolder);

View file

@ -15,7 +15,7 @@ namespace SecondBotEvents.Services
{
public class DiscordService : BotServices
{
protected Config.DiscordConfig myConfig = null;
protected new Config.DiscordConfig myConfig = null;
protected bool AcceptEventsFromSL = false;
protected bool DiscordIsReady = false;
protected bool DiscordDisconnectExpected = false;

View file

@ -13,7 +13,7 @@ namespace SecondBotEvents.Services
{
public class EventsService : BotServices
{
protected EventsConfig myConfig;
protected new EventsConfig myConfig;
protected bool botConnected = false;
protected string lastSimName = "";
protected UUID TrackGroupUUID = UUID.Zero;

View file

@ -8,7 +8,7 @@ namespace SecondBotEvents.Services
{
public class HomeboundService : BotServices
{
protected HomeboundConfig myConfig;
protected new HomeboundConfig myConfig;
protected bool botConnected = false;

View file

@ -20,7 +20,7 @@ namespace SecondBotEvents.Services
public class HttpService : BotServices
{
protected WebServer HTTPendpoint = null;
protected HttpConfig myConfig;
protected new HttpConfig myConfig;
protected bool acceptBotCommands = false;
public HttpService(EventsSecondBot setMaster) : base(setMaster)
{

View file

@ -11,7 +11,7 @@ namespace SecondBotEvents.Services
{
public class InteractionService : BotServices
{
protected InteractionConfig myConfig;
protected new InteractionConfig myConfig;
protected bool botConnected = false;
public InteractionService(EventsSecondBot setMaster) : base(setMaster)
{

View file

@ -16,7 +16,7 @@ namespace SecondBotEvents.Services
{
public class RelayService : BotServices
{
protected RelayConfig myConfig;
protected new RelayConfig myConfig;
protected bool botConnected = false;
public RelayService(EventsSecondBot setMaster) : base(setMaster)
{

View file

@ -2,18 +2,31 @@
using System;
using System.Collections.Generic;
using System.Text;
using SecondBotEvents.Config;
namespace SecondBotEvents.Services
{
public abstract class BotServices
{
public EventsSecondBot master;
protected Config.Config myConfig;
protected bool running = false;
public BotServices(EventsSecondBot setMaster)
{
master = setMaster;
}
public void enableAndStart()
{
myConfig.setEnabled(true);
Restart();
}
public void changeConfig(string configKey, string configValue)
{
myConfig.updateKey(configKey, configValue);
}
public bool isRunning() { return running; }
public GridClient GetClient()

View file

@ -27,6 +27,7 @@ namespace SecondBotEvents
reply.Add("parcel", typeof(ParcelCommands));
reply.Add("self", typeof(Self));
reply.Add("streamadmin", typeof(StreamAdmin));
reply.Add("services", typeof(SecondBotEvents.Commands.Services));
return reply;
}
}

View file

@ -55,7 +55,7 @@ namespace SecondBotEvents
string card = "<div class=\"card mt-2 mx-2\" style=\"width: 18rem;\">"
+ "<div class=\"card-body\">"
+ "<h5 class=\"card-title\">" + namespaceworker.FirstCharToUpper() + "</h5>"
+ "<p class=\"card-text\">" + about + "</p>"
+ "<p class=\"card-text\">" + about.Split("<br")[0] + "</p>"
+ "<a href = \"" + url + "\" class=\"btn btn-primary\">View " + commandcount.ToString() + " commands</a>"
+ "</div>"
+ "</div>";