Compare commits

...

3 commits

Author SHA1 Message Date
Marco Mariani 4018e67819 online api permissions 2023-11-15 13:36:33 +01:00
Marco Mariani d1b7ac16cf local api permissions 2023-11-15 13:36:33 +01:00
Marco Mariani ef00f1b658 default "cscli machines add" to write credentials to stdout, require
explicit path to overwrite local_api_credentials.yaml
2023-11-15 11:56:23 +01:00
4 changed files with 42 additions and 19 deletions

View file

@ -215,7 +215,7 @@ func restoreConfigFromDirectory(dirPath string, oldBackup bool) error {
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)
if err != nil {
return fmt.Errorf("write api credentials in '%s' failed: %s", apiConfigDumpFile, err)
}

View file

@ -149,7 +149,7 @@ 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)
}

View file

@ -43,6 +43,7 @@ func generatePassword(length int) string {
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 {
@ -180,7 +181,7 @@ cscli machines add MyTestMachine --password MyPassword
flags := cmdMachinesAdd.Flags()
flags.StringP("password", "p", "", "machine password to login to the API")
flags.StringP("file", "f", "", "output file destination (defaults to "+csconfig.DefaultConfigPath("local_api_credentials.yaml")+")")
flags.StringP("file", "f", "-", "output file destination (defaults to stdout)")
flags.StringP("url", "u", "", "URL of the local API")
flags.BoolP("interactive", "i", false, "interfactive mode to enter the password")
flags.BoolP("auto", "a", false, "automatically generate password (and username if not provided)")
@ -190,7 +191,6 @@ cscli machines add MyTestMachine --password MyPassword
}
func runMachinesAdd(cmd *cobra.Command, args []string) error {
var dumpFile string
var err error
flags := cmd.Flags()
@ -200,11 +200,15 @@ func runMachinesAdd(cmd *cobra.Command, args []string) error {
return err
}
outputFile, err := flags.GetString("file")
dumpFile, err := flags.GetString("file")
if err != nil {
return err
}
if dumpFile == "-" {
dumpFile = ""
}
apiURL, err := flags.GetString("url")
if err != nil {
return err
@ -241,13 +245,6 @@ func runMachinesAdd(cmd *cobra.Command, args []string) error {
machineID = args[0]
}
/*check if file already exists*/
if outputFile != "" {
dumpFile = outputFile
} else if csConfig.API.Client != nil && csConfig.API.Client.CredentialsFilePath != "" {
dumpFile = csConfig.API.Client.CredentialsFilePath
}
// create a password if it's not specified by user
if machinePassword == "" && !interactive {
if !autoAdd {
@ -267,6 +264,9 @@ func runMachinesAdd(cmd *cobra.Command, args []string) error {
return fmt.Errorf("unable to create machine: %s", err)
}
log.Infof("Machine '%s' successfully added to the local API", machineID)
if dumpFile == "" {
log.Infof("You need to copy the following lines to local_api_credentials.yaml on the new machine (make sure to restrict the file permissions)")
}
if apiURL == "" {
if csConfig.API.Client != nil && csConfig.API.Client.Credentials != nil && csConfig.API.Client.Credentials.URL != "" {
@ -286,14 +286,15 @@ func runMachinesAdd(cmd *cobra.Command, args []string) error {
if err != nil {
return fmt.Errorf("unable to marshal api credentials: %s", err)
}
if dumpFile != "" && dumpFile != "-" {
err = os.WriteFile(dumpFile, apiConfigDump, 0644)
if err != nil {
return fmt.Errorf("write api credentials in '%s' failed: %s", dumpFile, err)
}
log.Printf("API credentials dumped to '%s'", dumpFile)
} else {
if dumpFile == "" {
fmt.Printf("%s\n", string(apiConfigDump))
} else {
err = os.WriteFile(dumpFile, apiConfigDump, 0o600)
if err != nil {
return fmt.Errorf("writing api credentials to '%s': %s", dumpFile, err)
}
log.Infof("API credentials dumped to '%s'", dumpFile)
}
return nil

View file

@ -13,6 +13,7 @@ teardown_file() {
setup() {
load "../lib/setup.sh"
load "../lib/bats-file/load.bash"
./instance-data load
./instance-crowdsec start
}
@ -33,6 +34,27 @@ teardown() {
assert_output '[1,"githubciXXXXXXXXXXXXXXXXXXXXXXXX",true]'
}
@test "adding a machines prints credentials (to stdout by default)" {
rune -0 cscli machines add testmachine --password testpassword
rune -0 yq -o json . <(output)
assert_json '{login: "testmachine", password: "testpassword", url: "http://127.0.0.1:8080"}'
rune -1 cscli machines add testmachine --password testpassword
assert_stderr --partial "unable to create machine: user 'testmachine': user already exist"
# the "-" name as stdout still works
rune -0 cscli machines add testmachine2 --password testpassword -f -
rune -0 yq -o json . <(output)
assert_json '{login: "testmachine2", password: "testpassword", url: "http://127.0.0.1:8080"}'
tempfile="${BATS_TEST_TMPDIR}/testmachine.yml"
rune -0 cscli machines add testmachine3 --password testpassword -f "${tempfile}"
assert_stderr --partial "API credentials dumped to '${tempfile}'"
rune -0 yq -o json . < "$tempfile"
assert_json '{login: "testmachine3", password: "testpassword", url: "http://127.0.0.1:8080"}'
assert_file_permission 600 "$tempfile"
}
@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"