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

cscli machines add: don't overwrite existing credential file #2625

Merged
merged 2 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/crowdsec-cli/capi.go
Expand Up @@ -110,7 +110,7 @@ func NewCapiRegisterCmd() *cobra.Command {
if err != nil {
return fmt.Errorf("write api credentials in '%s' failed: %w", dumpFile, err)
}
log.Printf("Central API credentials dumped to '%s'", dumpFile)
log.Printf("Central API credentials written to '%s'", dumpFile)
} else {
fmt.Printf("%s\n", string(apiConfigDump))
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/crowdsec-cli/config_restore.go
Expand Up @@ -183,7 +183,7 @@
if csConfig.API.Server.OnlineClient != nil && csConfig.API.Server.OnlineClient.CredentialsFilePath != "" {
apiConfigDumpFile = csConfig.API.Server.OnlineClient.CredentialsFilePath
}
err = os.WriteFile(apiConfigDumpFile, apiConfigDump, 0o644)
err = os.WriteFile(apiConfigDumpFile, apiConfigDump, 0o600)

Check warning on line 186 in cmd/crowdsec-cli/config_restore.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_restore.go#L186

Added line #L186 was not covered by tests
if err != nil {
return fmt.Errorf("write api credentials in '%s' failed: %s", apiConfigDumpFile, err)
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/crowdsec-cli/lapi.go
Expand Up @@ -150,11 +150,11 @@ func runLapiRegister(cmd *cobra.Command, args []string) error {
log.Fatalf("unable to marshal api credentials: %s", err)
}
if dumpFile != "" {
err = os.WriteFile(dumpFile, apiConfigDump, 0644)
err = os.WriteFile(dumpFile, apiConfigDump, 0o600)
if err != nil {
log.Fatalf("write api credentials in '%s' failed: %s", dumpFile, err)
}
log.Printf("Local API credentials dumped to '%s'", dumpFile)
log.Printf("Local API credentials written to '%s'", dumpFile)
} else {
fmt.Printf("%s\n", string(apiConfigDump))
}
Expand Down
33 changes: 22 additions & 11 deletions cmd/crowdsec-cli/machines.go
Expand Up @@ -43,6 +43,7 @@
charsetLength := len(charset)

buf := make([]byte, length)

for i := 0; i < length; i++ {
rInt, err := saferand.Int(saferand.Reader, big.NewInt(int64(charsetLength)))
if err != nil {
Expand Down Expand Up @@ -190,7 +191,6 @@
}

func runMachinesAdd(cmd *cobra.Command, args []string) error {
var dumpFile string
var err error

flags := cmd.Flags()
Expand All @@ -200,7 +200,7 @@
return err
}

outputFile, err := flags.GetString("file")
dumpFile, err := flags.GetString("file")
if err != nil {
return err
}
Expand All @@ -220,7 +220,7 @@
return err
}

forceAdd, err := flags.GetBool("force")
force, err := flags.GetBool("force")
if err != nil {
return err
}
Expand All @@ -242,17 +242,28 @@
}

/*check if file already exists*/
if outputFile != "" {
dumpFile = outputFile
} else if csConfig.API.Client != nil && csConfig.API.Client.CredentialsFilePath != "" {
dumpFile = csConfig.API.Client.CredentialsFilePath
if dumpFile == "" && csConfig.API.Client != nil && csConfig.API.Client.CredentialsFilePath != "" {
credFile := csConfig.API.Client.CredentialsFilePath
// use the default only if the file does not exist
_, err := os.Stat(credFile)
switch {
case os.IsNotExist(err) || force:
dumpFile = csConfig.API.Client.CredentialsFilePath
case err != nil:
return fmt.Errorf("unable to stat '%s': %s", credFile, err)

Check warning on line 253 in cmd/crowdsec-cli/machines.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/machines.go#L252-L253

Added lines #L252 - L253 were not covered by tests
default:
return fmt.Errorf(`credentials file '%s' already exists: please remove it, use "--force" or specify a different file with "-f" ("-f -" for standard output)`, credFile)
}
}

if dumpFile == "" {
return fmt.Errorf(`please specify a file to dump credentials to, with -f ("-f -" for standard output)`)

Check warning on line 260 in cmd/crowdsec-cli/machines.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/machines.go#L260

Added line #L260 was not covered by tests
}

// create a password if it's not specified by user
if machinePassword == "" && !interactive {
if !autoAdd {
printHelp(cmd)
return nil
return fmt.Errorf("please specify a password with --password or use --auto")

Check warning on line 266 in cmd/crowdsec-cli/machines.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/machines.go#L266

Added line #L266 was not covered by tests
}
machinePassword = generatePassword(passwordLength)
} else if machinePassword == "" && interactive {
Expand All @@ -262,7 +273,7 @@
survey.AskOne(qs, &machinePassword)
}
password := strfmt.Password(machinePassword)
_, err = dbClient.CreateMachine(&machineID, &password, "", true, forceAdd, types.PasswordAuthType)
_, err = dbClient.CreateMachine(&machineID, &password, "", true, force, types.PasswordAuthType)
if err != nil {
return fmt.Errorf("unable to create machine: %s", err)
}
Expand Down Expand Up @@ -291,7 +302,7 @@
if err != nil {
return fmt.Errorf("write api credentials in '%s' failed: %s", dumpFile, err)
}
log.Printf("API credentials dumped to '%s'", dumpFile)
log.Printf("API credentials written to '%s'", dumpFile)
} else {
fmt.Printf("%s\n", string(apiConfigDump))
}
Expand Down
16 changes: 10 additions & 6 deletions test/bats/30_machines.bats
Expand Up @@ -23,20 +23,24 @@ teardown() {

#----------

@test "can list machines as regular user" {
rune -0 cscli machines list
}

@test "we have exactly one machine" {
rune -0 cscli machines list -o json
rune -0 jq -c '[. | length, .[0].machineId[0:32], .[0].isValidated]' <(output)
assert_output '[1,"githubciXXXXXXXXXXXXXXXXXXXXXXXX",true]'
}

@test "don't overwrite local credentials by default" {
rune -1 cscli machines add local -a -o json
rune -0 jq -r '.msg' <(stderr)
assert_output --partial 'already exists: please remove it, use "--force" or specify a different file with "-f"'
rune -0 cscli machines add local -a --force
assert_stderr --partial "Machine 'local' successfully added to the local API"
}

@test "add a new machine and delete it" {
rune -0 cscli machines add -a -f /dev/null CiTestMachine -o human
assert_stderr --partial "Machine 'CiTestMachine' successfully added to the local API"
assert_stderr --partial "API credentials dumped to '/dev/null'"
assert_stderr --partial "API credentials written to '/dev/null'"

# we now have two machines
rune -0 cscli machines list -o json
Expand All @@ -56,7 +60,7 @@ teardown() {
@test "register, validate and then remove a machine" {
rune -0 cscli lapi register --machine CiTestMachineRegister -f /dev/null -o human
assert_stderr --partial "Successfully registered to Local API (LAPI)"
assert_stderr --partial "Local API credentials dumped to '/dev/null'"
assert_stderr --partial "Local API credentials written to '/dev/null'"

# the machine is not validated yet
rune -0 cscli machines list -o json
Expand Down
6 changes: 3 additions & 3 deletions test/lib/config/config-global
Expand Up @@ -61,12 +61,12 @@ make_init_data() {
./instance-db config-yaml
./instance-db setup

./bin/preload-hub-items

# when installed packages are always using sqlite, so no need to regenerate
# local credz for sqlite

./bin/preload-hub-items

[[ "${DB_BACKEND}" == "sqlite" ]] || ${CSCLI} machines add --auto
[[ "${DB_BACKEND}" == "sqlite" ]] || ${CSCLI} machines add githubciXXXXXXXXXXXXXXXXXXXXXXXX --auto --force

mkdir -p "$LOCAL_INIT_DIR"

Expand Down
3 changes: 2 additions & 1 deletion test/lib/config/config-local
Expand Up @@ -115,11 +115,12 @@ make_init_data() {
./instance-db config-yaml
./instance-db setup

"$CSCLI" --warning machines add githubciXXXXXXXXXXXXXXXXXXXXXXXX --auto
"$CSCLI" --warning hub update

./bin/preload-hub-items

"$CSCLI" --warning machines add githubciXXXXXXXXXXXXXXXXXXXXXXXX --auto --force

mkdir -p "$LOCAL_INIT_DIR"

./instance-db dump "${LOCAL_INIT_DIR}/database"
Expand Down