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 != "" { if csConfig.API.Server.OnlineClient != nil && csConfig.API.Server.OnlineClient.CredentialsFilePath != "" {
apiConfigDumpFile = 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 { if err != nil {
return fmt.Errorf("write api credentials in '%s' failed: %s", apiConfigDumpFile, err) 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) log.Fatalf("unable to marshal api credentials: %s", err)
} }
if dumpFile != "" { if dumpFile != "" {
err = os.WriteFile(dumpFile, apiConfigDump, 0644) err = os.WriteFile(dumpFile, apiConfigDump, 0o600)
if err != nil { if err != nil {
log.Fatalf("write api credentials in '%s' failed: %s", dumpFile, err) 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) charsetLength := len(charset)
buf := make([]byte, length) buf := make([]byte, length)
for i := 0; i < length; i++ { for i := 0; i < length; i++ {
rInt, err := saferand.Int(saferand.Reader, big.NewInt(int64(charsetLength))) rInt, err := saferand.Int(saferand.Reader, big.NewInt(int64(charsetLength)))
if err != nil { if err != nil {
@ -180,7 +181,7 @@ cscli machines add MyTestMachine --password MyPassword
flags := cmdMachinesAdd.Flags() flags := cmdMachinesAdd.Flags()
flags.StringP("password", "p", "", "machine password to login to the API") 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.StringP("url", "u", "", "URL of the local API")
flags.BoolP("interactive", "i", false, "interfactive mode to enter the password") flags.BoolP("interactive", "i", false, "interfactive mode to enter the password")
flags.BoolP("auto", "a", false, "automatically generate password (and username if not provided)") 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 { func runMachinesAdd(cmd *cobra.Command, args []string) error {
var dumpFile string
var err error var err error
flags := cmd.Flags() flags := cmd.Flags()
@ -200,11 +200,15 @@ func runMachinesAdd(cmd *cobra.Command, args []string) error {
return err return err
} }
outputFile, err := flags.GetString("file") dumpFile, err := flags.GetString("file")
if err != nil { if err != nil {
return err return err
} }
if dumpFile == "-" {
dumpFile = ""
}
apiURL, err := flags.GetString("url") apiURL, err := flags.GetString("url")
if err != nil { if err != nil {
return err return err
@ -241,13 +245,6 @@ func runMachinesAdd(cmd *cobra.Command, args []string) error {
machineID = args[0] 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 // create a password if it's not specified by user
if machinePassword == "" && !interactive { if machinePassword == "" && !interactive {
if !autoAdd { if !autoAdd {
@ -267,6 +264,9 @@ func runMachinesAdd(cmd *cobra.Command, args []string) error {
return fmt.Errorf("unable to create machine: %s", err) return fmt.Errorf("unable to create machine: %s", err)
} }
log.Infof("Machine '%s' successfully added to the local API", machineID) 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 apiURL == "" {
if csConfig.API.Client != nil && csConfig.API.Client.Credentials != nil && csConfig.API.Client.Credentials.URL != "" { 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 { if err != nil {
return fmt.Errorf("unable to marshal api credentials: %s", err) return fmt.Errorf("unable to marshal api credentials: %s", err)
} }
if dumpFile != "" && dumpFile != "-" {
err = os.WriteFile(dumpFile, apiConfigDump, 0644) if dumpFile == "" {
if err != nil {
return fmt.Errorf("write api credentials in '%s' failed: %s", dumpFile, err)
}
log.Printf("API credentials dumped to '%s'", dumpFile)
} else {
fmt.Printf("%s\n", string(apiConfigDump)) 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 return nil

View file

@ -13,6 +13,7 @@ teardown_file() {
setup() { setup() {
load "../lib/setup.sh" load "../lib/setup.sh"
load "../lib/bats-file/load.bash"
./instance-data load ./instance-data load
./instance-crowdsec start ./instance-crowdsec start
} }
@ -33,6 +34,27 @@ teardown() {
assert_output '[1,"githubciXXXXXXXXXXXXXXXXXXXXXXXX",true]' 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" { @test "add a new machine and delete it" {
rune -0 cscli machines add -a -f /dev/null CiTestMachine -o human 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 "Machine 'CiTestMachine' successfully added to the local API"