470 lines
15 KiB
Go
470 lines
15 KiB
Go
// # Miscellaneous Commands
|
|
//
|
|
// The Miscellaneous section provides a diverse set of administrative methods for
|
|
// system diagnostics, real-time monitoring, and low-level server control.
|
|
//
|
|
// Key capabilities include:
|
|
// - System Inspection: retrieving server version, OS details, start time,
|
|
// and cluster instances via [Cli.GetSystemInfo] and predefined [SystemInfoKey] constants.
|
|
// - Dynamic IP Protection: managing temporary blacklists and unblockable IP lists
|
|
// to mitigate brute-force attacks in real-time.
|
|
// - Queue Management: monitoring and managing the message delivery pipeline,
|
|
// including the ability to reject or release messages from SMTP queues.
|
|
// - Diagnostics & Logging: controlling trace facilities (FileIO/FileOp),
|
|
// toggling "Log Everything" mode, and writing custom entries to the system log.
|
|
// - Cluster Operations: force-reconnecting cluster administration channels and
|
|
// identifying the current Dynamic Cluster Controller.
|
|
package cgpcli
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"time"
|
|
)
|
|
|
|
// SystemInfoKey represents a recognized key for server metadata retrieval.
|
|
type SystemInfoKey string
|
|
|
|
const (
|
|
SysVersion SystemInfoKey = "serverVersion" // e.g., "6.3.20"
|
|
SysOS SystemInfoKey = "serverOS" // Target Operating System
|
|
SysCPU SystemInfoKey = "serverCPU" // CPU Architecture
|
|
SysMainDomain SystemInfoKey = "mainDomainName"
|
|
SysLicenseDomain SystemInfoKey = "licenseDomainName"
|
|
SysStartTime SystemInfoKey = "startTime" // Server boot time
|
|
SysServerInstance SystemInfoKey = "serverInstance"
|
|
SysClusterInstance SystemInfoKey = "clusterInstance"
|
|
SysCharsets SystemInfoKey = "knownCharsets"
|
|
SysDigesters SystemInfoKey = "knownDigesters"
|
|
SysCiphers SystemInfoKey = "knownCiphers" // Supported SSL/TLS ciphers
|
|
)
|
|
|
|
// TraceFacility defines specific server modules available for real-time tracing.
|
|
type TraceFacility string
|
|
|
|
const (
|
|
TraceFileIO TraceFacility = "FileIO" // Record all file read/write/truncate operations
|
|
TraceFileOp TraceFacility = "FileOp" // Record all file create/rename/remove operations
|
|
)
|
|
|
|
// DumpAllObjects writes the list of all application data objects.
|
|
//
|
|
// Parameters:
|
|
// - file: if true, the objects_dump.txt file is created in the Server base directory.
|
|
// If false, the list is written into the OS syslog.
|
|
//
|
|
// Note: This list may contain millions of objects and can overload the OS syslog.
|
|
// It also effectively suspends CommuniGate Pro Server activities till all objects are listed.
|
|
//
|
|
// This method executes the DUMPALLOBJECTS CLI command.
|
|
//
|
|
// Returns:
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) DumpAllObjects(file bool) error {
|
|
const cmd = "DUMPALLOBJECTS"
|
|
if file {
|
|
return cli.QueryNV(cmd, "FILE")
|
|
} else {
|
|
return cli.QueryNV(cmd)
|
|
}
|
|
}
|
|
|
|
// Echo produces an output which is a copy of the command parameter object.
|
|
//
|
|
// Parameters:
|
|
// - obj: the object (string, dictionary, array, etc.) to be echoed back by the server.
|
|
//
|
|
// This method executes the ECHO CLI command.
|
|
//
|
|
// Returns:
|
|
// - any: the exact copy of the input object as returned by the server.
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) Echo(obj any) (any, error) {
|
|
return cli.Query("ECHO", obj)
|
|
}
|
|
|
|
// GetCurrentController retrieves the IP address of the current Dynamic Cluster Controller.
|
|
//
|
|
// This method executes the GETCURRENTCONTROLLER CLI command.
|
|
//
|
|
// Returns:
|
|
// - net.IP: the Cluster Controller IP Address.
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) GetCurrentController() (net.IP, error) {
|
|
s, err := cli.getString("GETCURRENTCONTROLLER")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if s == "" {
|
|
return nil, nil
|
|
}
|
|
return net.ParseIP(s), nil
|
|
}
|
|
|
|
// GetCurrentTime retrieves the current internal timer value of the CommuniGate Pro Server.
|
|
//
|
|
// This method executes the GETCURRENTTIME CLI command.
|
|
//
|
|
// Returns:
|
|
// - time.Time: a timestamp with the Server internal timer value.
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) GetCurrentTime() (time.Time, error) {
|
|
const cmd = "GETCURRENTTIME"
|
|
res, err := cli.Query(cmd)
|
|
if err != nil {
|
|
return time.Time{}, err
|
|
}
|
|
t, ok := res.(time.Time)
|
|
if !ok {
|
|
return time.Time{}, fmt.Errorf("%s: expected time.Time, got %T", cmd, res)
|
|
}
|
|
return t, nil
|
|
}
|
|
|
|
// GetMessageQueueInfo reads information about a module message Queue.
|
|
//
|
|
// Parameters:
|
|
// - module: the module name.
|
|
// - queue: the module queue name.
|
|
//
|
|
// This method executes the GETMESSAGEQUEUEINFO CLI command.
|
|
//
|
|
// Returns:
|
|
// - map[string]any: a dictionary with the specified queue information (nTotal, size, delayedTill, lastError).
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) GetMessageQueueInfo(module, queue string) (map[string]any, error) {
|
|
if module == "" || queue == "" {
|
|
return nil, fmt.Errorf("module and queue are required")
|
|
}
|
|
return cli.getMapAny("GETMESSAGEQUEUEINFO", module, "QUEUE", queue)
|
|
}
|
|
|
|
// GetSystemInfo retrieves information returned by the CG/PL SystemInfo function called with the what parameter.
|
|
//
|
|
// Parameters:
|
|
// - what: the system information key to retrieve.
|
|
//
|
|
// This method executes the GETSYSTEMINFO CLI command.
|
|
//
|
|
// Returns:
|
|
// - any: an object returned by the SystemInfo function.
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) GetSystemInfo(what SystemInfoKey) (any, error) {
|
|
if what == "" {
|
|
return nil, fmt.Errorf("system info key is required")
|
|
}
|
|
return cli.Query("GETSYSTEMINFO", string(what))
|
|
}
|
|
|
|
// GetTempBlacklistedIPs retrieves the set of Temporarily Blocked Addresses.
|
|
//
|
|
// This method executes the GETTEMPBLACKLISTEDIPS CLI command.
|
|
//
|
|
// Returns:
|
|
// - *[TempIPList]: a list of Temporary Blocked IP addresses. Each address may have a suffix indicating the block duration.
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) GetTempBlacklistedIPs() (*TempIPList, error) {
|
|
raw, err := cli.getString("GETTEMPBLACKLISTEDIPS")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &TempIPList{items: parseTempIPsToMap(raw)}, nil
|
|
}
|
|
|
|
// GetTempClientIPs retrieves the set of temporary Client IP Addresses.
|
|
//
|
|
// This method executes the GETTEMPCLIENTIPS CLI command.
|
|
//
|
|
// Returns:
|
|
// - *[TempIPList]: a list of Temporary Client IP addresses.
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) GetTempClientIPs() (*TempIPList, error) {
|
|
raw, err := cli.getString("GETTEMPCLIENTIPS")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &TempIPList{items: parseTempIPsToMap(raw)}, nil
|
|
}
|
|
|
|
// GetTempUnblockableIPs retrieves the set of Temporary UnBlockable IP Addresses.
|
|
//
|
|
// This method executes the GETTEMPUNBLOCKABLEIPS CLI command.
|
|
//
|
|
// Returns:
|
|
// - *[TempIPList]: a list of Temporary UnBlockable IP addresses.
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) GetTempUnblockableIPs() (*TempIPList, error) {
|
|
raw, err := cli.getString("GETTEMPUNBLOCKABLEIPS")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &TempIPList{items: parseTempIPsToMap(raw)}, nil
|
|
}
|
|
|
|
// GetVersion retrieves the current CommuniGate Pro Server version.
|
|
//
|
|
// This method executes the GETVERSION CLI command.
|
|
//
|
|
// Returns:
|
|
// - string: a string with the server version.
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) GetVersion() (string, error) {
|
|
return cli.getString("GETVERSION")
|
|
}
|
|
|
|
// ListCLICommands retrieves the list of all CLI commands supported by this version of CommuniGate Pro Server.
|
|
//
|
|
// This method executes the LISTCLICOMMANDS CLI command.
|
|
//
|
|
// Returns:
|
|
// - []string: an array of strings, where each string is a supported command name.
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) ListCLICommands() ([]string, error) {
|
|
return cli.getSliceString("LISTCLICOMMANDS")
|
|
}
|
|
|
|
// Noop is a command that always completes successfully.
|
|
//
|
|
// This method executes the NOOP CLI command.
|
|
//
|
|
// Returns:
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) Noop() error {
|
|
return cli.QueryNV("NOOP")
|
|
}
|
|
|
|
// ReconnectClusterAdmin forces a Dynamic Cluster member to re-open all its inter-cluster Administrative connections.
|
|
//
|
|
// This method executes the RECONNECTCLUSTERADMIN CLI command.
|
|
//
|
|
// Returns:
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) ReconnectClusterAdmin() error {
|
|
return cli.QueryNV("RECONNECTCLUSTERADMIN")
|
|
}
|
|
|
|
// RejectQueueMessage rejects a message from the Server Queue.
|
|
//
|
|
// Parameters:
|
|
// - id: the message ID.
|
|
// - report: an optional text to be included in the bounce report.
|
|
// If the parameter is "NONDN", no DSN report message is generated.
|
|
//
|
|
// This method executes the REJECTQUEUEMESSAGE CLI command.
|
|
//
|
|
// Returns:
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) RejectQueueMessage(id int64, report string) error {
|
|
if report != "" {
|
|
return cli.QueryNV("REJECTQUEUEMESSAGE", id, "REPORT", report)
|
|
} else {
|
|
return cli.QueryNV("REJECTQUEUEMESSAGE", id)
|
|
}
|
|
}
|
|
|
|
// RejectQueueMessages rejects all messages sent by the specified sender from the Server Queue.
|
|
//
|
|
// Parameters:
|
|
// - sender: the authenticated sender's name.
|
|
// - report: an optional text to be included in the bounce report.
|
|
// If the parameter is "NONDN", no DSN report message is generated.
|
|
//
|
|
// Note: In a Dynamic Cluster environment this command rejects messages from all server queues.
|
|
//
|
|
// This method executes the REJECTQUEUEMESSAGES CLI command.
|
|
//
|
|
// Returns:
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) RejectQueueMessages(sender, report string) error {
|
|
if sender == "" {
|
|
return fmt.Errorf("sender is required")
|
|
}
|
|
|
|
if report != "" {
|
|
return cli.QueryNV("REJECTQUEUEMESSAGES", "SENDER", sender, "REPORT", report)
|
|
} else {
|
|
return cli.QueryNV("REJECTQUEUEMESSAGES", "SENDER", sender)
|
|
}
|
|
}
|
|
|
|
// ReleaseSMTPQueue releases an SMTP queue.
|
|
//
|
|
// Parameters:
|
|
// - queue: the queue (domain) name to release.
|
|
//
|
|
// Note: In a Dynamic Cluster environment this command releases the specified SMTP queue on all servers.
|
|
//
|
|
// This method executes the RELEASESMTPQUEUE CLI command.
|
|
//
|
|
// Returns:
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) ReleaseSMTPQueue(queue string) error {
|
|
if queue == "" {
|
|
return fmt.Errorf("queue name is required")
|
|
}
|
|
return cli.QueryNV("RELEASESMTPQUEUE", queue)
|
|
}
|
|
|
|
// ReportFailedLoginAddress increments the counter of failed Login attempts from the specified IP address.
|
|
//
|
|
// Parameters:
|
|
// - ip: the Network IP Address to report.
|
|
//
|
|
// This method executes the REPORTFAILEDLOGINADDRESS CLI command.
|
|
//
|
|
// Returns:
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) ReportFailedLoginAddress(ip net.IP) error {
|
|
if ip == nil {
|
|
return fmt.Errorf("IP address is required")
|
|
}
|
|
return cli.QueryNV("REPORTFAILEDLOGINADDRESS", ip.String())
|
|
}
|
|
|
|
// SetLogAll switches on and off the "Log Everything" mode.
|
|
//
|
|
// Parameters:
|
|
// - on: boolean to switch the mode ON or OFF.
|
|
//
|
|
// This method executes the SETLOGALL CLI command.
|
|
//
|
|
// Returns:
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) SetLogAll(on bool) error {
|
|
val := "OFF"
|
|
if on {
|
|
val = "ON"
|
|
}
|
|
return cli.QueryNV("SETLOGALL", val)
|
|
}
|
|
|
|
// SetTempBlacklistedIPs adds addresses to the Temporary Blocked IP Addresses list.
|
|
//
|
|
// Parameters:
|
|
// - list: a list of IP addresses in the format of the GetTempBlacklistedIPs command.
|
|
//
|
|
// This method executes the SETTEMPBLACKLISTEDIPS CLI command.
|
|
//
|
|
// Returns:
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) SetTempBlacklistedIPs(list *TempIPList) error {
|
|
if list == nil || list.Len() == 0 {
|
|
return cli.QueryNV("SETTEMPBLACKLISTEDIPS", "")
|
|
}
|
|
return cli.QueryNV("SETTEMPBLACKLISTEDIPS", list)
|
|
}
|
|
|
|
// SetTempUnblockableIPs adds addresses to the Temporary UnBlockable IP Addresses set.
|
|
//
|
|
// Parameters:
|
|
// - list: a list of IP addresses in the format of the GetTempUnBlockableIPs command.
|
|
//
|
|
// This method executes the SETTEMPBLACKLISTEDIPS CLI command.
|
|
//
|
|
// Returns:
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) SetTempUnblockableIPs(list *TempIPList) error {
|
|
if list == nil || list.Len() == 0 {
|
|
return cli.QueryNV("SETTEMPBLACKLISTEDIPS", "")
|
|
}
|
|
return cli.QueryNV("SETTEMPUNBLOCKABLEIPS", list)
|
|
}
|
|
|
|
// SetTrace switches on and off internal logging facilities that write to OS syslog.
|
|
//
|
|
// Parameters:
|
|
// - facility: the facility name.
|
|
// - on: boolean to switch the facility ON or OFF.
|
|
//
|
|
// This method executes the SETTRACE CLI command.
|
|
//
|
|
// Returns:
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) SetTrace(facility TraceFacility, on bool) error {
|
|
if facility == "" {
|
|
return fmt.Errorf("trace facility is required")
|
|
}
|
|
|
|
val := "OFF"
|
|
if on {
|
|
val = "ON"
|
|
}
|
|
return cli.QueryNV("SETTRACE", string(facility), val)
|
|
}
|
|
|
|
// TempBlacklistIP adds or removes an address from the Temporarily Blocked Addresses set.
|
|
//
|
|
// Parameters:
|
|
// - ip: the Network IP Address to add or remove.
|
|
// - timeout: the time period the address should be blocked for. Use 0 or DELETE to remove.
|
|
//
|
|
// This method executes the TEMPBLACKLISTIP CLI command.
|
|
//
|
|
// Returns:
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) TempBlacklistIP(ip net.IP, timeout time.Duration) error {
|
|
if ip == nil {
|
|
return fmt.Errorf("IP address is required")
|
|
}
|
|
|
|
if timeout <= 0 {
|
|
return cli.QueryNV("TEMPBLACKLISTIP", ip.String(), "DELETE")
|
|
} else {
|
|
return cli.QueryNV("TEMPBLACKLISTIP", ip.String(), "TIMEOUT", int(timeout.Seconds()))
|
|
}
|
|
}
|
|
|
|
// TempUnblockIP adds or removes an address from the Temporary UnBlockable IP Addresses set.
|
|
//
|
|
// Parameters:
|
|
// - ip: the Network IP Address to add or remove.
|
|
// - timeout: the time period the address should be in the set. Use 0 or DELETE to remove.
|
|
//
|
|
// This method executes the TEMPUNBLOCKIP CLI command.
|
|
//
|
|
// Returns:
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) TempUnblockIP(ip net.IP, timeout time.Duration) error {
|
|
if ip == nil {
|
|
return fmt.Errorf("IP address is required")
|
|
}
|
|
|
|
if timeout <= 0 {
|
|
return cli.QueryNV("TEMPUNBLOCKIP", ip.String(), "DELETE")
|
|
} else {
|
|
return cli.QueryNV("TEMPUNBLOCKIP", ip.String(), "TIMEOUT", int(timeout.Seconds()))
|
|
}
|
|
}
|
|
|
|
// TestLoop tests the server CPU load by executing a calculation loop for the specified number of seconds.
|
|
//
|
|
// Parameters:
|
|
// - seconds: duration of the test in seconds.
|
|
//
|
|
// This method executes the TESTLOOP CLI command.
|
|
//
|
|
// Returns:
|
|
// - int: a number that indicates the average CLI thread CPU performance.
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) TestLoop(seconds int) (int, error) {
|
|
res, err := cli.Query("TESTLOOP", seconds)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return toInt(res), nil
|
|
}
|
|
|
|
// WriteLog stores a record into the Server Log. Log records have the SYSTEM prefix.
|
|
//
|
|
// Parameters:
|
|
// - level: the record log level.
|
|
// - record: the string to be placed into the Server Log.
|
|
//
|
|
// This method executes the WRITELOG CLI command.
|
|
//
|
|
// Returns:
|
|
// - error: an error if the command fails.
|
|
func (cli *Cli) WriteLog(level int, record string) error {
|
|
return cli.QueryNV("WRITELOG", level, record)
|
|
}
|