diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..47e4cd1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.build-docker diff --git a/rados/conn.go b/rados/conn.go index b833968..381fa4c 100644 --- a/rados/conn.go +++ b/rados/conn.go @@ -262,6 +262,15 @@ func (c *Conn) DeletePool(name string) error { // MonCommand sends a command to one of the monitors func (c *Conn) MonCommand(args []byte) (buffer []byte, info string, err error) { + return c.monCommand(args, nil) +} + +// MonCommand sends a command to one of the monitors, with an input buffer +func (c *Conn) MonCommandWithInputBuffer(args, inputBuffer []byte) (buffer []byte, info string, err error) { + return c.monCommand(args, inputBuffer) +} + +func (c *Conn) monCommand(args, inputBuffer []byte) (buffer []byte, info string, err error) { argv := C.CString(string(args)) defer C.free(unsafe.Pointer(argv)) @@ -269,16 +278,17 @@ func (c *Conn) MonCommand(args []byte) (buffer []byte, info string, err error) { outs, outbuf *C.char outslen, outbuflen C.size_t ) - inbuf := C.CString("") + inbuf := C.CString(string(inputBuffer)) + inbufLen := len(inputBuffer) defer C.free(unsafe.Pointer(inbuf)) ret := C.rados_mon_command(c.cluster, &argv, 1, - inbuf, // bulk input (e.g. crush map) - C.size_t(0), // length inbuf - &outbuf, // buffer - &outbuflen, // buffer length - &outs, // status string + inbuf, // bulk input (e.g. crush map) + C.size_t(inbufLen), // length inbuf + &outbuf, // buffer + &outbuflen, // buffer length + &outs, // status string &outslen) if outslen > 0 { diff --git a/rados/rados_test.go b/rados/rados_test.go index c72e6ab..b0f8159 100644 --- a/rados/rados_test.go +++ b/rados/rados_test.go @@ -477,6 +477,7 @@ func TestMonCommand(t *testing.T) { conn, _ := rados.NewConn() conn.ReadDefaultConfigFile() conn.Connect() + defer conn.Shutdown() command, err := json.Marshal(map[string]string{"prefix": "df", "format": "json"}) assert.NoError(t, err) @@ -488,8 +489,43 @@ func TestMonCommand(t *testing.T) { var message map[string]interface{} err = json.Unmarshal(buf, &message) assert.NoError(t, err) +} - conn.Shutdown() +func TestMonCommandWithInputBuffer(t *testing.T) { + conn, _ := rados.NewConn() + conn.ReadDefaultConfigFile() + conn.Connect() + defer conn.Shutdown() + + // first add the new test user, specifying its key in the input buffer + command, err := json.Marshal(map[string]interface{}{ + "prefix": "auth add", + "format": "json", + "entity": "client.testMonCommandUser", + }) + assert.NoError(t, err) + + inbuf := []byte(`[client.testMonCommandUser] +key = AQD4PGNXBZJNHhAA582iUgxe9DsN+MqFN4Z6Jw== +`) + + buf, info, err := conn.MonCommandWithInputBuffer(command, inbuf) + assert.NoError(t, err) + assert.Equal(t, "added key for client.testMonCommandUser", info) + assert.Equal(t, "", string(buf[:])) + + // now get the key, and verify it is equal to the key we specified in the input buffer for "auth add" + command, err = json.Marshal(map[string]interface{}{ + "prefix": "auth get-key", + "format": "json", + "entity": "client.testMonCommandUser", + }) + assert.NoError(t, err) + + buf, info, err = conn.MonCommand(command) + assert.NoError(t, err) + assert.Equal(t, "", info) + assert.Equal(t, `{"key":"AQD4PGNXBZJNHhAA582iUgxe9DsN+MqFN4Z6Jw=="}`, string(buf[:])) } func TestObjectListObjects(t *testing.T) {