Skip to content

Commit

Permalink
fix bugs and linter errors
Browse files Browse the repository at this point in the history
  • Loading branch information
chadpatel committed Dec 17, 2024
1 parent aa25c3f commit 5986b7f
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 101 deletions.
1 change: 1 addition & 0 deletions cmd/amazon-cloudwatch-agent/amazon-cloudwatch-agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
"github.com/aws/amazon-cloudwatch-agent/internal/version"
cwaLogger "github.com/aws/amazon-cloudwatch-agent/logger"
"github.com/aws/amazon-cloudwatch-agent/logs"
_ "github.com/aws/amazon-cloudwatch-agent/plugins" // do not remove, necessary for telegraf to know what plugins are used
"github.com/aws/amazon-cloudwatch-agent/profiler"
"github.com/aws/amazon-cloudwatch-agent/receiver/adapter"
"github.com/aws/amazon-cloudwatch-agent/service/configprovider"
Expand Down
4 changes: 2 additions & 2 deletions tool/cmdwrapper/cmdwrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
)

type Flag struct {
Name string
DefaultValue string
Description string
}
Expand All @@ -28,7 +27,7 @@ var execCommand = exec.Command
func AddFlags(prefix string, flagConfigs map[string]Flag) map[string]*string {
flags := make(map[string]*string)
for key, flagConfig := range flagConfigs {
flagName := flagConfig.Name
flagName := key
if prefix != "" {
flagName = prefix + delimiter + flagName
}
Expand All @@ -52,6 +51,7 @@ func ExecuteAgentCommand(command string, flags map[string]*string) error {
cmd := execCommand(paths.AgentBinaryPath, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin

if err := cmd.Run(); err != nil {
var exitErr *exec.ExitError
Expand Down
2 changes: 0 additions & 2 deletions tool/cmdwrapper/cmdwrapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ func TestAddFlags(t *testing.T) {
prefix: "",
flagConfigs: map[string]Flag{
"test": {
Name: "test",
DefaultValue: "default",
Description: "test description",
},
Expand All @@ -40,7 +39,6 @@ func TestAddFlags(t *testing.T) {
prefix: "prefix",
flagConfigs: map[string]Flag{
"test": {
Name: "test",
DefaultValue: "default",
Description: "test description",
},
Expand Down
110 changes: 48 additions & 62 deletions tool/downloader/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,8 @@ const (
locationFile = "file"

locationSeparator = ":"

exitErrorMessage = "Fail to fetch the config!"
)

func EscapeFilePath(filePath string) (escapedFilePath string) {
escapedFilePath = filepath.ToSlash(filePath)
escapedFilePath = strings.Replace(escapedFilePath, "/", "_", -1)
escapedFilePath = strings.Replace(escapedFilePath, " ", "_", -1)
escapedFilePath = strings.Replace(escapedFilePath, ":", "_", -1)
return
}

func RunDownloaderFromFlags(flags map[string]*string) error {
return RunDownloader(
*flags["mode"],
Expand All @@ -50,19 +40,14 @@ func RunDownloaderFromFlags(flags map[string]*string) error {
)
}

/**
* multi-config:
* default, append: download config to the dir and append .tmp suffix
* remove: remove the config from the dir
*/
func RunDownloader(
mode string,
downloadLocation string,
outputDir string,
inputConfig string,
multiConfig string,
) error {
// Initialize common config
func RunDownloader(mode, downloadLocation, outputDir, inputConfig, multiConfig string) error {
defer func() {
if r := recover(); r != nil {
fmt.Println("Fail to fetch the config!")
os.Exit(1)
}
}()

cc := commonconfig.New()
if inputConfig != "" {
f, err := os.Open(inputConfig)
Expand Down Expand Up @@ -93,49 +78,29 @@ func RunDownloader(
// Detect agent mode and region
mode = sdkutil.DetectAgentMode(mode)
region, _ := util.DetectRegion(mode, cc.CredentialsMap())

// Validate region
if region == "" && downloadLocation != locationDefault {
if mode == config.ModeEC2 {
return fmt.Errorf("please check if you can access the metadata service. For example, on linux, run 'wget -q -O - http://169.254.169.254/latest/meta-data/instance-id && echo'")
}
return fmt.Errorf("please make sure the credentials and region set correctly on your hosts")
}

// Clean up output directory
err := filepath.Walk(outputDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("cannot access %v: %v", path, err)
}
if info.IsDir() {
if strings.EqualFold(path, outputDir) {
return nil
}
fmt.Printf("Sub dir %v will be ignored.", path)
return filepath.SkipDir
}
if filepath.Ext(path) == constants.FileSuffixTmp {
return os.Remove(path)
}
return nil
})
err := cleanupOutputDir(outputDir)
if err != nil {
return err
return fmt.Errorf("failed to clean up output directory: %v", err)
}

// Parse download location
locationArray := strings.SplitN(downloadLocation, locationSeparator, 2)
if locationArray == nil || len(locationArray) < 2 && downloadLocation != locationDefault {
return fmt.Errorf("downloadLocation %s is malformed", downloadLocation)
}

// Process configuration based on location type
var config, outputFilePath string
switch locationArray[0] {
case locationDefault:
outputFilePath = locationDefault
if multiConfig != "remove" {
config, err = defaultJsonConfig(mode)
config, err = defaultJSONConfig(mode)
}
case locationSSM:
outputFilePath = locationSSM + "_" + EscapeFilePath(locationArray[1])
Expand All @@ -152,32 +117,29 @@ func RunDownloader(
}

if err != nil {
return err
return fmt.Errorf("fail to fetch/remove json config: %v", err)
}

// Handle configuration based on multiConfig setting
if multiConfig == "remove" {
outputPath := filepath.Join(outputDir, outputFilePath)
if err := os.Remove(outputPath); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("failed to remove file %s: %v", outputPath, err)
}
} else {
if multiConfig != "remove" {
outputPath := filepath.Join(outputDir, outputFilePath+constants.FileSuffixTmp)
if err := os.WriteFile(outputPath, []byte(config), 0644); err != nil {

Check failure on line 125 in tool/downloader/downloader.go

View workflow job for this annotation

GitHub Actions / Check lint

G306: Expect WriteFile permissions to be 0600 or less (gosec)
return fmt.Errorf("failed to write to file %s: %v", outputPath, err)
return fmt.Errorf("failed to write the json file %v: %v", outputPath, err)
}
} else {
outputPath := filepath.Join(outputDir, outputFilePath)
if err := os.Remove(outputPath); err != nil {
return fmt.Errorf("failed to remove the json file %v: %v", outputPath, err)
}
}

return nil
}

func defaultJsonConfig(mode string) (string, error) {
func defaultJSONConfig(mode string) (string, error) {
return config.DefaultJsonConfig(config.ToValidOs(""), mode), nil
}

func downloadFromSSM(region, parameterStoreName, mode string, credsConfig map[string]string) (string, error) {
fmt.Printf("Region: %v\n", region)
fmt.Printf("credsConfig: %v\n", credsConfig)
var ses *session.Session
credsMap := util.GetCredentials(mode, credsConfig)
profile, profileOk := credsMap[commonconfig.CredentialProfile]
Expand All @@ -196,8 +158,7 @@ func downloadFromSSM(region, parameterStoreName, mode string, credsConfig map[st

ses, err := session.NewSession(rootconfig)
if err != nil {
fmt.Printf("Error in creating session: %v\n", err)
return "", err
return "", fmt.Errorf("error in creating session: %v", err)
}

ssmClient := ssm.New(ses)
Expand All @@ -207,8 +168,7 @@ func downloadFromSSM(region, parameterStoreName, mode string, credsConfig map[st
}
output, err := ssmClient.GetParameter(&input)
if err != nil {
fmt.Printf("Error in retrieving parameter store content: %v\n", err)
return "", err
return "", fmt.Errorf("error in retrieving parameter store content: %v", err)
}

return *output.Parameter.Value, nil
Expand All @@ -218,3 +178,29 @@ func readFromFile(filePath string) (string, error) {
bytes, err := os.ReadFile(filePath)
return string(bytes), err
}

func EscapeFilePath(filePath string) string {
escapedFilePath := filepath.ToSlash(filePath)
escapedFilePath = strings.Replace(escapedFilePath, "/", "_", -1)
escapedFilePath = strings.Replace(escapedFilePath, " ", "_", -1)
escapedFilePath = strings.Replace(escapedFilePath, ":", "_", -1)
return escapedFilePath
}

func cleanupOutputDir(outputDir string) error {
return filepath.Walk(outputDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("cannot access %v: %v", path, err)
}
if info.IsDir() {
if strings.EqualFold(path, outputDir) {
return nil
}
return filepath.SkipDir
}
if filepath.Ext(path) == constants.FileSuffixTmp {
return os.Remove(path)
}
return nil
})
}
10 changes: 5 additions & 5 deletions tool/downloader/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import "github.com/aws/amazon-cloudwatch-agent/tool/cmdwrapper"
const Command = "config-downloader"

var DownloaderFlags = map[string]cmdwrapper.Flag{
"mode": {"mode", "ec2", "Please provide the mode, i.e. ec2, onPremise, onPrem, auto"},
"download-source": {"download-source", "", "Download source. Example: \"ssm:my-parameter-store-name\" for an EC2 SSM Parameter Store Name holding your CloudWatch Agent configuration."},
"output-dir": {"output-dir", "", "Path of output json config directory."},
"config": {"config", "", "Please provide the common-config file"},
"multi-config": {"multi-config", "default", "valid values: default, append, remove"},
"mode": {DefaultValue: "ec2", Description: "Please provide the mode, i.e. ec2, onPremise, onPrem, auto"},
"download-source": {DefaultValue: "", Description: "Download source. Example: \"ssm:my-parameter-store-name\" for an EC2 SSM Parameter Store Name holding your CloudWatch Agent configuration."},
"output-dir": {DefaultValue: "", Description: "Path of output json config directory."},
"config": {DefaultValue: "", Description: "Please provide the common-config file"},
"multi-config": {DefaultValue: "default", Description: "valid values: default, append, remove"},
}
18 changes: 9 additions & 9 deletions tool/wizard/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ const (
)

var WizardFlags = map[string]cmdwrapper.Flag{
"is-non-interactive-windows-migration": {"isNonInteractiveWindowsMigration", "false", "If true, it will use command line args to bypass the wizard. Default value is false."},
"is-non-interactive-linux-migration": {"isNonInteractiveLinuxMigration", "false", "If true, it will do the linux config migration. Default value is false."},
"traces-only": {"tracesOnly", "false", "If true, only trace configuration will be generated"},
"use-parameter-store": {"useParameterStore", "false", "If true, it will use the parameter store for the migrated config storage."},
"non-interactive-xray-migration": {"nonInteractiveXrayMigration", "false", "If true, then this is part of non Interactive xray migration tool."},
"config-file-path": {"configFilePath", "", fmt.Sprintf("The path of the old config file. Default is %s on Windows or %s on Linux", DefaultFilePathWindowsConfiguration, DefaultFilePathLinuxConfiguration)},
"config-output-path": {"configOutputPath", "", "Specifies where to write the configuration file generated by the wizard"},
"parameter-store-name": {"parameterStoreName", "", "The parameter store name. Default is AmazonCloudWatch-windows"},
"parameter-store-region": {"parameterStoreRegion", "", "The parameter store region. Default is us-east-1"},
"is-non-interactive-windows-migration": {DefaultValue: "false", Description: "If true, it will use command line args to bypass the wizard. Default value is false."},
"is-non-interactive-linux-migration": {DefaultValue: "false", Description: "If true, it will do the linux config migration. Default value is false."},
"traces-only": {DefaultValue: "false", Description: "If true, only trace configuration will be generated"},
"use-parameter-store": {DefaultValue: "false", Description: "If true, it will use the parameter store for the migrated config storage."},
"non-interactive-xray-migration": {DefaultValue: "false", Description: "If true, then this is part of non Interactive xray migration tool."},
"config-file-path": {DefaultValue: "", Description: fmt.Sprintf("The path of the old config file. Default is %s on Windows or %s on Linux", DefaultFilePathWindowsConfiguration, DefaultFilePathLinuxConfiguration)},
"config-output-path": {DefaultValue: "", Description: "Specifies where to write the configuration file generated by the wizard"},
"parameter-store-name": {DefaultValue: "", Description: "The parameter store name. Default is AmazonCloudWatch-windows"},
"parameter-store-region": {DefaultValue: "", Description: "The parameter store region. Default is us-east-1"},
}
11 changes: 7 additions & 4 deletions tool/wizard/wizard.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
)

type IMainProcessor interface {
VerifyProcessor(processor interface{})
VerifyProcessor(_processor interface{})
}

type MainProcessorStruct struct{}
Expand All @@ -42,15 +42,18 @@ type Params struct {
}

func init() {
stdin.Scanln = func(a ...interface{}) (n int, err error) {
stdin.Scanln = func(a ...interface{}) (int, error) {
var n int
var err error

scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
if len(a) > 0 {
*a[0].(*string) = scanner.Text()
n = len(*a[0].(*string))
}
err = scanner.Err()
return
return n, err
}
processors.StartProcessor = basicInfo.Processor
}
Expand Down Expand Up @@ -140,5 +143,5 @@ func startProcessing(configOutputPath string, isNonInteractiveWindowsMigration,
}
}

func (p *MainProcessorStruct) VerifyProcessor(processor interface{}) {
func (p *MainProcessorStruct) VerifyProcessor(interface{}) {
}
18 changes: 9 additions & 9 deletions translator/cmdutil/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@ func RunTranslator(flags map[string]*string) error {
return ct.Translate()
}

func NewConfigTranslator(inputOs, inputJsonFile, inputJsonDir, inputTomlFile, inputMode, inputConfig, multiConfig string) (*ConfigTranslator, error) {
func NewConfigTranslator(inputOs, inputJSONFile, inputJSONDir, inputTOMLFile, inputMode, inputConfig, multiConfig string) (*ConfigTranslator, error) {

ct := ConfigTranslator{
ctx: context.CurrentContext(),
}

ct.ctx.SetOs(inputOs)
ct.ctx.SetInputJsonFilePath(inputJsonFile)
ct.ctx.SetInputJsonDirPath(inputJsonDir)
ct.ctx.SetInputJsonFilePath(inputJSONFile)
ct.ctx.SetInputJsonDirPath(inputJSONDir)
ct.ctx.SetMultiConfig(multiConfig)
ct.ctx.SetOutputTomlFilePath(inputTomlFile)
ct.ctx.SetOutputTomlFilePath(inputTOMLFile)

if inputConfig != "" {
f, err := os.Open(inputConfig)
Expand Down Expand Up @@ -97,15 +97,15 @@ func (ct *ConfigTranslator) Translate() error {
}
}()

mergedJsonConfigMap, err := GenerateMergedJsonConfigMap(ct.ctx)
mergedJSONConfigMap, err := GenerateMergedJsonConfigMap(ct.ctx)
if err != nil {
return fmt.Errorf("failed to generate merged json config: %v", err)
}

if !ct.ctx.RunInContainer() {
current, err := user.Current()
if err == nil && current.Name == "****" {
runAsUser, err := userutil.DetectRunAsUser(mergedJsonConfigMap)
runAsUser, err := userutil.DetectRunAsUser(mergedJSONConfigMap)
if err != nil {
return fmt.Errorf("failed to detectRunAsUser")
}
Expand All @@ -116,11 +116,11 @@ func (ct *ConfigTranslator) Translate() error {
tomlConfigPath := GetTomlConfigPath(ct.ctx.OutputTomlFilePath())
tomlConfigDir := filepath.Dir(tomlConfigPath)
yamlConfigPath := filepath.Join(tomlConfigDir, yamlConfigFileName)
tomlConfig, err := TranslateJsonMapToTomlConfig(mergedJsonConfigMap)
tomlConfig, err := TranslateJsonMapToTomlConfig(mergedJSONConfigMap)
if err != nil {
return fmt.Errorf("failed to generate TOML configuration validation content: %v", err)
}
yamlConfig, err := TranslateJsonMapToYamlConfig(mergedJsonConfigMap)
yamlConfig, err := TranslateJsonMapToYamlConfig(mergedJSONConfigMap)
if err != nil && !errors.Is(err, pipeline.ErrNoPipelines) {
return fmt.Errorf("failed to generate YAML configuration validation content: %v", err)
}
Expand All @@ -133,7 +133,7 @@ func (ct *ConfigTranslator) Translate() error {
log.Println(exitSuccessMessage)

envConfigPath := filepath.Join(tomlConfigDir, envConfigFileName)
TranslateJsonMapToEnvConfigFile(mergedJsonConfigMap, envConfigPath)
TranslateJsonMapToEnvConfigFile(mergedJSONConfigMap, envConfigPath)

return nil
}
2 changes: 1 addition & 1 deletion translator/cmdutil/translatorutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ func checkIfSchemaValidateAsExpected(t *testing.T, jsonInputPath string, shouldS
t.Logf("Type: %v \n", errorDetail.Type())
t.Logf("Value: %v \n", errorDetail.Value())
if _, ok := actualErrorMap[errorDetail.Type()]; ok {
actualErrorMap[errorDetail.Type()] += 1
actualErrorMap[errorDetail.Type()]++
} else {
actualErrorMap[errorDetail.Type()] = 1
}
Expand Down
Loading

0 comments on commit 5986b7f

Please sign in to comment.