Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Placeholders for RateLimitBurst and RateLimitImterval added #8635

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion api/config/shared/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package shared

import (
"fmt"
"github.com/pkg/errors"
"net/url"
"os/exec"
"strings"

"github.com/pkg/errors"

w "github.com/chef/automate/api/config/shared/wrappers"
"github.com/chef/automate/lib/io/fileutils"
"github.com/chef/automate/lib/proxy"
Expand Down
476 changes: 252 additions & 224 deletions api/config/shared/global.pb.go

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion api/config/shared/global.proto
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,8 @@ message Log {
google.protobuf.BoolValue compress_rotated_logs = 5;
google.protobuf.StringValue max_size_rotate_logs = 6;
google.protobuf.Int32Value max_number_rotated_logs = 7;

google.protobuf.Int32Value rate_limit_interval = 8;
google.protobuf.Int32Value rate_limit_burst = 9;
}

message Disclosure {
Expand Down
86 changes: 69 additions & 17 deletions components/automate-cli/cmd/chef-automate/centerliazed_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ import (
)

const (
rsyslogConfigFile = "/etc/rsyslog.d/automate.conf"
logRotateConfigFile = "/etc/logrotate.d/automate"
postgresLogConfig = "/hab/a2_deploy_workspace/postgres_log.toml"
opensearchConfig = "/hab/a2_deploy_workspace/opensearch_log.toml"
restartSyslogService = "sudo systemctl restart rsyslog.service"
rsyslogConfigFile = "/etc/rsyslog.d/automate.conf"
logRotateConfigFile = "/etc/logrotate.d/automate"
postgresLogConfig = "/hab/a2_deploy_workspace/postgres_log.toml"
opensearchConfig = "/hab/a2_deploy_workspace/opensearch_log.toml"
restartSyslogService = "sudo systemctl restart rsyslog.service"
defaultRateLimitBurstAutomateSyslog = int32(200)
defaultRateLimitIntervalAutomateSyslog = int32(200) // in ms
globalV1Log = "global.v1.log"
)

// enableCentralizedLogConfigForHA checks for requested and existing configuration for logging
Expand All @@ -30,7 +33,6 @@ func enableCentralizedLogConfigForHA(args []string, remoteType string, sshUtil S
}
//Returning if there is no config set for logging
if reqConfig.GetGlobal().GetV1().GetLog() == nil {

return nil
}
existConfig, err := getPostgresOrOpenSearchExistingLogConfig(remoteType)
Expand All @@ -55,7 +57,7 @@ func enableCentralizedLogging(reqConfig *dc.AutomateConfig, existConfig *dc.Auto
return nil
}

err := createRsyslogAndLogRotateConfig(sshUtil, remoteIp, scriptCommands, remoteType)
err := createRsyslogAndLogRotateConfig(sshUtil, remoteIp, scriptCommands, remoteType, true)
if err != nil {
return err
}
Expand Down Expand Up @@ -109,7 +111,10 @@ func getScriptCommandsForConfigChangedLogging(reqConfig *dc.AutomateConfig, exis
if reqConfig.GetGlobal().GetV1().GetLog().GetRedirectSysLog().GetValue() == false &&
existConfig.GetGlobal().GetV1().GetLog().GetRedirectSysLog().GetValue() == true {
scriptCommands = rollBackCentralized()
} else if reqConfig.GetGlobal().GetV1().GetLog().GetRedirectLogFilePath().GetValue() == existConfig.GetGlobal().GetV1().GetLog().GetRedirectLogFilePath().GetValue() {
} else if existConfig.GetGlobal().GetV1().GetLog().GetRedirectSysLog().GetValue() &&
reqConfig.GetGlobal().GetV1().GetLog().GetRedirectLogFilePath().GetValue() == existConfig.GetGlobal().GetV1().GetLog().GetRedirectLogFilePath().GetValue() &&
reqConfig.GetGlobal().GetV1().GetLog().GetRateLimitBurst().GetValue() == existConfig.GetGlobal().GetV1().GetLog().GetRateLimitBurst().GetValue() &&
reqConfig.GetGlobal().GetV1().GetLog().GetRateLimitInterval().GetValue() == existConfig.GetGlobal().GetV1().GetLog().GetRateLimitInterval().GetValue() {
logrotateFileCommand := fmt.Sprintf("echo \"%s\" > %s", configLogrotate(reqConfig.GetGlobal().GetV1().GetLog()), logRotateConfigFile)
return fmt.Sprintf("sudo sh -c '%s'", logrotateFileCommand)

Expand Down Expand Up @@ -139,10 +144,12 @@ func configLogrotate(req *shared.Log) string {

// createConfigFileForAutomateSysLog created a config file as /etc/rsyslog.d/automate.conf
// which redirects the logs to the specified location
func createConfigFileForAutomateSysLog(pathForLog string) string {
return fmt.Sprintf(`if \$programname == \"bash\" then %s
& stop`, getLogFileName(pathForLog))

func createConfigFileForAutomateSysLog(pathForLog string, rateLimitBurst int32, rateLimitInterval int32) string {
return fmt.Sprintf(`\$imjournalRatelimitBurst %d
\$imjournalRatelimitInterval %d
if \$programname == \"bash\" then %s
& stop
`, rateLimitBurst, rateLimitInterval, getLogFileName(pathForLog))
}

// LogRotateConf gets the log rotate configuration using the values from config
Expand Down Expand Up @@ -182,6 +189,32 @@ func decodeLogConfig(logConfig string) (*dc.AutomateConfig, error) {
return &src, nil
}

func removeOrUpdateCentralisedLog(args []string, remoteType string, sshUtil SSHUtil, remoteIp []string) error {
req, err := getConfigForArgsLogs(args, remoteType)
if err != nil {
return err
}
var scriptCommands string

if req.GetGlobal().GetV1().GetLog().GetRedirectSysLog().GetValue() == false {
scriptCommands = rollBackCentralized()
} else if req.GetGlobal().GetV1().GetLog().GetRedirectSysLog().GetValue() {
scriptCommands = rollBackCentralized()
if err := req.GetGlobal().ValidateReDirectSysLogConfig(); err != nil {
return err
}
scriptCommands += createScriptCommandsForCentralizedLog(req)
}
if len(scriptCommands) == 0 {
return nil
}
err = createRsyslogAndLogRotateConfig(sshUtil, remoteIp, scriptCommands, remoteType, false)
if err != nil {
return err
}
return nil
}

// getConfigForArgsLogs get the requested config from the patched file
func getConfigForArgsLogs(args []string, remoteService string) (*dc.AutomateConfig, error) {

Expand All @@ -206,12 +239,28 @@ func rollBackCentralized() string {

logRotateFileRemove := fmt.Sprintf("sudo rm %s", logRotateConfigFile)

return fmt.Sprintf(" %s; %s; %s", rsyslogFileRemove, logRotateFileRemove, restartSyslogService)
return fmt.Sprintf(" %s; %s; %s;", rsyslogFileRemove, logRotateFileRemove, restartSyslogService)
}

// Initially rateLimitBurst and rateLimitInterval have default values for the respective service i.e automatesyslog or journald.
func getRateLimitValues(req *dc.AutomateConfig, rateLimitBurst int32, rateLimitInterval int32) (int32, int32) {
// now in current req, if user pass new value then use this value
if req.GetGlobal().GetV1().GetLog().GetRateLimitBurst().GetValue() > 0 {
rateLimitBurst = req.GetGlobal().GetV1().GetLog().GetRateLimitBurst().GetValue()
}

// now in current req, if user pass new value then use this value
if req.GetGlobal().GetV1().GetLog().GetRateLimitInterval().GetValue() > 0 {
rateLimitInterval = req.GetGlobal().GetV1().GetLog().GetRateLimitInterval().GetValue()
}

return rateLimitBurst, rateLimitInterval
}

// setConfigForCentralizedLog sets config for rsyslog and logrotate
func createScriptCommandsForCentralizedLog(reqConfig *dc.AutomateConfig) string {
contentForRsyslogConfig := createConfigFileForAutomateSysLog(reqConfig.GetGlobal().GetV1().GetLog().GetRedirectLogFilePath().GetValue())
rateLimitBurstAutomateSyslog, rateLimitIntervalAutomateSyslog := getRateLimitValues(reqConfig, defaultRateLimitBurstAutomateSyslog, defaultRateLimitIntervalAutomateSyslog)
contentForRsyslogConfig := createConfigFileForAutomateSysLog(reqConfig.GetGlobal().GetV1().GetLog().GetRedirectLogFilePath().GetValue(), rateLimitBurstAutomateSyslog, rateLimitIntervalAutomateSyslog)

//creating a file and adding content in the file
rsysCreateFileCommand := fmt.Sprintf("echo \"%s\" > %s", contentForRsyslogConfig, rsyslogConfigFile)
Expand All @@ -224,16 +273,19 @@ func createScriptCommandsForCentralizedLog(reqConfig *dc.AutomateConfig) string
}

// createRsyslogAndLogRotateConfig patching the config into the remote database servers
func createRsyslogAndLogRotateConfig(sshUtil SSHUtil, remoteIp []string, scriptCommands string, remoteService string) error {
func createRsyslogAndLogRotateConfig(sshUtil SSHUtil, remoteIp []string, scriptCommands string, remoteService string, print bool) error {
for i := 0; i < len(remoteIp); i++ {
sshUtil.getSSHConfig().hostIP = remoteIp[i]
output, err := sshUtil.connectAndExecuteCommandOnRemote(scriptCommands, true)
if err != nil {
writer.Errorf("%v", err)
return err
}
writer.Printf(output)
writer.Success("Patching is completed on " + remoteService + " node : " + remoteIp[i] + "\n")
// Adding this if condition, because RateLimit Config is shared between centralized logging and systemd. Otherwise it's Printing twice
if print {
writer.Printf(output)
writer.Success("Patching is completed on " + remoteService + " node : " + remoteIp[i] + "\n")
}

}
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package main

import (
"fmt"
"testing"

dc "github.com/chef/automate/api/config/deployment"
"github.com/chef/automate/api/config/shared"
w "github.com/chef/automate/api/config/shared/wrappers"
"github.com/stretchr/testify/assert"
"testing"
)

func TestGetScriptCommandsForConfigChangedLogging(t *testing.T) {
Expand Down Expand Up @@ -193,7 +194,7 @@ func TestGetScriptCommandsForLogging(t *testing.T) {
},
},
},
want: ` sudo rm /etc/rsyslog.d/automate.conf; sudo rm /etc/logrotate.d/automate; sudo systemctl restart rsyslog.service`,
want: ` sudo rm /etc/rsyslog.d/automate.conf; sudo rm /etc/logrotate.d/automate; sudo systemctl restart rsyslog.service;`,
},
{
name: "Get Script Commands if there is config changed in the requested and existed config has more values",
Expand Down
103 changes: 89 additions & 14 deletions components/automate-cli/cmd/chef-automate/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,17 @@ func runPatchCommand(cmd *cobra.Command, args []string) error {
if configCmdFlags.waitTimeout < DEFAULT_TIMEOUT {
return errors.Errorf("The operation timeout duration for each individual node during the config patch process should be set to a value greater than %v seconds.", DEFAULT_TIMEOUT)
}

isRateLimiterConfig, err := checkIfRequestedConfigHasRateLimit(args)
if err != nil {
return err
}
if (configCmdFlags.opensearch || configCmdFlags.postgresql) && isRateLimiterConfig {
if err := patchRateLimitForBackend(args, infra); err != nil {
return err
}
}

isLoggerConfig, err := checkIfRequestedConfigHasCentrailisedLogging(args)
if err != nil {
return err
Expand All @@ -492,6 +503,20 @@ func runPatchCommand(cmd *cobra.Command, args []string) error {
}
}

if (configCmdFlags.opensearch || configCmdFlags.postgresql) && isRateLimiterConfig && !isLoggerConfig {
modifiedConfig, err := removeRateLimiterConfig(args)
if err != nil {
return err
}
checkIfConfigHasOnlyLogConfig, err := checkUserConfigHasOnlyCentrailisedLogConfig(modifiedConfig)
if err != nil {
return err
}
if checkIfConfigHasOnlyLogConfig {
return nil
}
}

configFile := args[0]
configFileName := stringutils.GetFileName(configFile)
frontendPrefix := "frontend" + "_" + timestamp + "_"
Expand Down Expand Up @@ -590,7 +615,7 @@ func runPatchCommand(cmd *cobra.Command, args []string) error {
} else {
writer.Println(cmd.UsageString())
}
if (configCmdFlags.opensearch || configCmdFlags.postgresql) && isLoggerConfig {
if (configCmdFlags.opensearch || configCmdFlags.postgresql) && (isLoggerConfig || isRateLimiterConfig) {
os.Remove(configFile)
}

Expand All @@ -599,7 +624,6 @@ func runPatchCommand(cmd *cobra.Command, args []string) error {
if err != nil {
return status.Annotate(err, status.ConfigError)
}

// keep chefserver fqdn same as automate fqdn in case of standalone automate
if !checkIfFileExist(automateHaPath) && cfg.GetGlobal().GetV1().GetChefServer() != nil && cfg.GetGlobal().GetV1().GetChefServer().GetFqdn() != nil {
res, err := client.GetAutomateConfig(configCmdFlags.timeout)
Expand Down Expand Up @@ -638,13 +662,13 @@ func patchAndRemoveCentralisedLoggingForBackend(args []string, infra *AutomateHA
}
writer.Success("Centralised logging configuration is patched. \n")
if configCmdFlags.postgresql {
inputfile, err = removeCentralisedLogsFromUserConfigForPg(args[0])
inputfile, err = removeCentralisedLogsandRateLimitFromUserConfigForPg(args[0])
if err != nil {
return "", err
}
}
if configCmdFlags.opensearch {
inputfile, err = removeCentralisedLogsFromUserConfigForOs(args[0])
inputfile, err = removeCentralisedLogsandRateLimitFromUserConfigForOs(args[0])
if err != nil {
return "", err
}
Expand Down Expand Up @@ -986,9 +1010,13 @@ func setConfigForPostgresqlNodes(args []string, remoteService string, sshUtil SS
return nil
}

//checking for RateLimit configuration
if err := removeOrUpdateRateLimit(args, remoteService, sshUtil, infra.Outputs.PostgresqlPrivateIps.Value); err != nil {
return err
}

//checking for log configuration
err := enableCentralizedLogConfigForHA(args, remoteService, sshUtil, infra.Outputs.PostgresqlPrivateIps.Value)
if err != nil {
if err := removeOrUpdateCentralisedLog(args, remoteService, sshUtil, infra.Outputs.PostgresqlPrivateIps.Value); err != nil {
return err
}

Expand Down Expand Up @@ -1020,9 +1048,13 @@ func setConfigForOpensearch(args []string, remoteService string, sshUtil SSHUtil
return nil
}

//checking for RateLimit configuration
if err := removeOrUpdateRateLimit(args, remoteService, sshUtil, infra.Outputs.OpensearchPrivateIps.Value); err != nil {
return err
}

//checking for log configuration
err := enableCentralizedLogConfigForHA(args, remoteService, sshUtil, infra.Outputs.OpensearchPrivateIps.Value)
if err != nil {
if err := removeOrUpdateCentralisedLog(args, remoteService, sshUtil, infra.Outputs.OpensearchPrivateIps.Value); err != nil {
return err
}

Expand Down Expand Up @@ -1286,11 +1318,54 @@ func checkIfRequestedConfigHasCentrailisedLogging(args []string) (bool, error) {
writer.Println(err.Error())
return false, err
}
if config.Get("global.v1.log") != nil {
isconfig := config.Get("global.v1.log").(*ptoml.Tree)
if config.Get(globalV1Log) != nil {
isconfig := config.Get(globalV1Log).(*ptoml.Tree)
if isconfig != nil {
if isconfig.Get("redirect_sys_log") != nil {
return true, nil
}
}
}
return false, nil
}

func checkIfExistedConfigHasCentrailisedLogging(fileName string) (bool, error) {
config, err := ptoml.LoadFile(fileName)
if err != nil {
writer.Println(err.Error())
return false, err
}
if config.Get(globalV1Log) != nil {
isconfig := config.Get(globalV1Log).(*ptoml.Tree)
if isconfig != nil {
if isconfig.Get("redirect_sys_log") != nil {
val := isconfig.Get("redirect_sys_log").(bool)
if val {
return true, nil
}
}
}
}
return false, nil
}

func checkIfRequestedConfigHasRateLimit(args []string) (bool, error) {
config, err := ptoml.LoadFile(args[0])
if err != nil {
writer.Println(err.Error())
return false, err
}
if config.Get(globalV1Log) != nil {
isconfig := config.Get(globalV1Log).(*ptoml.Tree)
if isconfig != nil {
val := isconfig.Get("redirect_sys_log").(bool)
if val == true {
var rateLimitInterval, rateLimitBurst int64 = 0, 0
if isconfig.Get("rate_limit_interval") != nil {
rateLimitInterval = isconfig.Get("rate_limit_interval").(int64)
}
if isconfig.Get("rate_limit_burst") != nil {
rateLimitBurst = isconfig.Get("rate_limit_burst").(int64)
}
if rateLimitInterval > 0 || rateLimitBurst > 0 {
return true, nil
}
}
Expand Down Expand Up @@ -1378,7 +1453,7 @@ func parseAndRemoveRestrictedKeysFromSrcFile(srcString string) (string, error) {
}
}

func removeCentralisedLogsFromUserConfigForPg(srcString string) (string, error) {
func removeCentralisedLogsandRateLimitFromUserConfigForPg(srcString string) (string, error) {
tomlbyt, _ := os.ReadFile(srcString)
destString := string(tomlbyt)
var dest PostgresqlConfig
Expand All @@ -1395,7 +1470,7 @@ func removeCentralisedLogsFromUserConfigForPg(srcString string) (string, error)
return newSrcString, nil
}

func removeCentralisedLogsFromUserConfigForOs(srcString string) (string, error) {
func removeCentralisedLogsandRateLimitFromUserConfigForOs(srcString string) (string, error) {
tomlbyt, _ := os.ReadFile(srcString)
destString := string(tomlbyt)
var dest OpensearchConfig
Expand Down
Loading
Loading