Example #1
0
// runSetUser invokes the REST API with POST action and username as
// path. Prompts for the password twice on stdin.
// TODO(marc): once we have more fields in the user config, we will need
// to allow changing just some of them (eg: change email, but leave password).
func runSetUser(cmd *cobra.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		return
	}
	hashed, err := security.PromptForPasswordAndHash()
	if err != nil {
		log.Error(err)
		return
	}
	// Build a UserConfig object. RunSetUser expects Yaml.
	// TODO(marc): re-work admin client library to take other encodings.
	pb := &proto.UserConfig{HashedPassword: hashed}
	contents, err := yaml.Marshal(pb)
	if err != nil {
		log.Error(err)
		return
	}
	admin := client.NewAdminClient(&Context.Context, Context.Addr, client.User)
	if err := admin.SetYAML(args[0], string(contents)); err != nil {
		log.Error(err)
		return
	}
	fmt.Printf("Wrote user config for %q\n", args[0])
}
Example #2
0
// runExterminate destroys the data held in the specified stores.
func runExterminate(cmd *cobra.Command, args []string) {
	if err := context.InitStores(); err != nil {
		log.Errorf("failed to initialize context: %s", err)
		return
	}

	// First attempt to shutdown the server. Note that an error of EOF just
	// means the HTTP server shutdown before the request to quit returned.
	admin := client.NewAdminClient(&context.Context, context.Addr, client.Quit)
	body, err := admin.Get()
	if err != nil {
		log.Infof("shutdown node %s: %s", context.Addr, err)
	} else {
		log.Infof("shutdown node in anticipation of data extermination: %s", body)
	}

	// Exterminate all data held in specified stores.
	for _, e := range context.Engines {
		if rocksdb, ok := e.(*engine.RocksDB); ok {
			log.Infof("exterminating data from store %s", e)
			if err := rocksdb.Destroy(); err != nil {
				log.Errorf("unable to destroy store %s: %s", e, err)
				osExit(1)
			}
		}
	}
	log.Infof("exterminated all data from stores %s", context.Engines)
}
Example #3
0
// runQuit accesses the quit shutdown path.
func runQuit(cmd *cobra.Command, args []string) {
	admin := client.NewAdminClient(&context.Context, context.Addr, client.Quit)
	body, err := admin.Get()
	if err != nil {
		fmt.Printf("shutdown node error: %s\n", err)
		osExit(1)
		return
	}
	fmt.Printf("node drained and shutdown: %s\n", body)
}
Example #4
0
// runRmZone invokes the REST API with DELETE action and key prefix as
// path.
func runRmZone(cmd *cobra.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		return
	}
	admin := client.NewAdminClient(&Context.Context, Context.Addr, client.Zone)
	if err := admin.Delete(args[0]); err != nil {
		log.Error(err)
		return
	}
	fmt.Printf("Deleted zone key %q\n", args[0])
}
Example #5
0
// runRmPerms invokes the REST API with DELETE action and key prefix as
// path.
func runRmPerms(cmd *cobra.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		return
	}
	admin := client.NewAdminClient(&context.Context, context.Addr, client.Permission)
	if err := admin.Delete(args[0]); err != nil {
		log.Error(err)
		return
	}
	fmt.Printf("Deleted permission key %q\n", args[0])
}
Example #6
0
// runLsAccts invokes the REST API with GET action and no path, which
// fetches a list of all acct configuration prefixes.
func runLsAccts(cmd *cobra.Command, args []string) {
	if len(args) > 0 {
		cmd.Usage()
		return
	}
	admin := client.NewAdminClient(&Context.Context, Context.Addr, client.Accounting)
	list, err := admin.List()
	if err != nil {
		log.Error(err)
		return
	}
	fmt.Printf("Accounting keys:\n%s\n", strings.Join(list, "\n  "))
}
Example #7
0
// runGetAcct invokes the REST API with GET action and key prefix as path.
func runGetAcct(cmd *cobra.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		return
	}
	admin := client.NewAdminClient(&Context.Context, Context.Addr, client.Accounting)
	body, err := admin.GetYAML(args[0])
	if err != nil {
		log.Error(err)
		return
	}
	fmt.Printf("Accounting config for prefix %q:\n%s\n", args[0], body)
}
Example #8
0
// runSetAcct invokes the REST API with POST action and key prefix as
// path. The specified configuration file is read from disk and sent
// as the POST body.
func runSetAcct(cmd *cobra.Command, args []string) {
	if len(args) != 2 {
		cmd.Usage()
		return
	}
	// Read in the config file.
	body, err := ioutil.ReadFile(args[1])
	if err != nil {
		log.Errorf("unable to read accounting config file %q: %s", args[1], err)
		return
	}
	admin := client.NewAdminClient(&Context.Context, Context.Addr, client.Accounting)
	if err := admin.SetYAML(args[0], string(body)); err != nil {
		log.Error(err)
		return
	}
	fmt.Printf("Wrote accounting config to %q\n", args[0])
}
Example #9
0
// Example_zone shows how to use the admin client to
// get/set/list/delete zone configs.
func Example_zone() {
	s := server.StartTestServer(nil)
	defer s.Stop()

	context := testutils.NewRootTestBaseContext()
	client := client.NewAdminClient(context, s.ServingAddr(), client.Zone)

	const yamlConfig = `
replicas:
  - attrs: [dc1, ssd]
  - attrs: [dc2, ssd]
  - attrs: [dc3, ssd]
range_min_bytes: 1048576
range_max_bytes: 67108864
`
	const jsonConfig = `{
	   "replica_attrs": [
	     {
	       "attrs": [
	         "dc1",
	         "ssd"
	       ]
	     },
	     {
	       "attrs": [
	         "dc2",
	         "ssd"
	       ]
	     },
	     {
	       "attrs": [
	         "dc3",
	         "ssd"
	       ]
	     }
	   ],
	   "range_min_bytes": 1048576,
	   "range_max_bytes": 67108864
	 }`

	testData := []struct {
		prefix proto.Key
		cfg    string
		isJSON bool
	}{
		{proto.KeyMin, yamlConfig, false},
		{proto.Key("db1"), yamlConfig, false},
		{proto.Key("db 2"), jsonConfig, true},
		{proto.Key("\xfe"), jsonConfig, true},
	}

	// Write configs.
	for _, test := range testData {
		prefix := string(test.prefix)
		if test.isJSON {
			fmt.Printf("Set JSON zone config for %q\n", prefix)
			if err := client.SetJSON(prefix, test.cfg); err != nil {
				log.Fatal(err)
			}
		} else {
			fmt.Printf("Set YAML zone config for %q\n", prefix)
			if err := client.SetYAML(prefix, test.cfg); err != nil {
				log.Fatal(err)
			}
		}
	}

	// Get configs in various format.
	body, err := client.GetJSON("db1")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("JSON config for \"db1\":\n%s\n", body)

	body, err = client.GetYAML("db 2")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("YAML config for \"db 2\":\n%s\n", body)

	// List keys.
	keys, err := client.List()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Zone prefixes: %q\n", keys)

	// Remove keys: the default one cannot be removed.
	err = client.Delete("")
	if err == nil {
		log.Fatal("expected error")
	}
	err = client.Delete("db 2")
	if err != nil {
		log.Fatal(err)
	}

	// List keys again.
	keys, err = client.List()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Zone prefixes: %q\n", keys)

	// Output:
	// Set YAML zone config for ""
	// Set YAML zone config for "db1"
	// Set JSON zone config for "db 2"
	// Set JSON zone config for "\xfe"
	// JSON config for "db1":
	// {
	//   "replica_attrs": [
	//     {
	//       "attrs": [
	//         "dc1",
	//         "ssd"
	//       ]
	//     },
	//     {
	//       "attrs": [
	//         "dc2",
	//         "ssd"
	//       ]
	//     },
	//     {
	//       "attrs": [
	//         "dc3",
	//         "ssd"
	//       ]
	//     }
	//   ],
	//   "range_min_bytes": 1048576,
	//   "range_max_bytes": 67108864
	// }
	// YAML config for "db 2":
	// replicas:
	// - attrs: [dc1, ssd]
	// - attrs: [dc2, ssd]
	// - attrs: [dc3, ssd]
	// range_min_bytes: 1048576
	// range_max_bytes: 67108864
	//
	// Zone prefixes: ["" "db 2" "db1" "\xfe"]
	// Zone prefixes: ["" "db1" "\xfe"]
}
Example #10
0
// Example_accounting shows how to use the admin client to
// get/set/list/delete accounting configs.
func Example_accounting() {
	s := server.StartTestServer(nil)
	defer s.Stop()

	context := testutils.NewRootTestBaseContext()
	client := client.NewAdminClient(context, s.ServingAddr(), client.Accounting)

	const yamlConfig = `cluster_id: test`
	const jsonConfig = `{
  "cluster_id": "test"
}`
	testData := []struct {
		prefix proto.Key
		cfg    string
		isJSON bool
	}{
		{proto.KeyMin, yamlConfig, false},
		{proto.Key("db1"), yamlConfig, false},
		{proto.Key("db 2"), jsonConfig, true},
		{proto.Key("\xfe"), jsonConfig, true},
	}

	// Write configs.
	for _, test := range testData {
		prefix := string(test.prefix)
		if test.isJSON {
			fmt.Printf("Set JSON accounting config for %q\n", prefix)
			if err := client.SetJSON(prefix, test.cfg); err != nil {
				log.Fatal(err)
			}
		} else {
			fmt.Printf("Set YAML accounting config for %q\n", prefix)
			if err := client.SetYAML(prefix, test.cfg); err != nil {
				log.Fatal(err)
			}
		}
	}

	// Get configs in various format.
	body, err := client.GetJSON("db1")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("JSON config for \"db1\":\n%s\n", body)

	body, err = client.GetYAML("db 2")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("YAML config for \"db 2\":\n%s\n", body)

	// List keys.
	keys, err := client.List()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Accounting prefixes: %q\n", keys)

	// Remove keys: the default one cannot be removed.
	err = client.Delete("")
	if err == nil {
		log.Fatal("expected error")
	}
	err = client.Delete("db 2")
	if err != nil {
		log.Fatal(err)
	}

	// List keys again.
	keys, err = client.List()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Accounting prefixes: %q\n", keys)

	// Output:
	// Set YAML accounting config for ""
	// Set YAML accounting config for "db1"
	// Set JSON accounting config for "db 2"
	// Set JSON accounting config for "\xfe"
	// JSON config for "db1":
	// {
	//   "cluster_id": "test"
	// }
	// YAML config for "db 2":
	// cluster_id: test
	//
	// Accounting prefixes: ["" "db 2" "db1" "\xfe"]
	// Accounting prefixes: ["" "db1" "\xfe"]
}
Example #11
0
// Example_user shows how to use the admin client to
// get/set/list/delete user configs.
func Example_user() {
	s := server.StartTestServer(nil)
	defer s.Stop()

	context := testutils.NewRootTestBaseContext()
	client := client.NewAdminClient(context, s.ServingAddr(), client.User)

	const yamlConfig = `hashed_password:
 - 10
 - 20`
	const jsonConfig = `{
	   "hashed_password": "******"
	 }`
	testData := []struct {
		prefix proto.Key
		cfg    string
		isJSON bool
	}{
		{proto.Key("db1"), yamlConfig, false},
		{proto.Key("db 2"), jsonConfig, true},
		{proto.Key("\xfe"), jsonConfig, true},
	}

	// Overwriting the default entry fails.
	err := client.SetYAML("", yamlConfig)
	if err == nil {
		log.Fatal("expected error")
	}

	// Write configs.
	for _, test := range testData {
		prefix := string(test.prefix)
		if test.isJSON {
			fmt.Printf("Set JSON user config for %q\n", prefix)
			if err := client.SetJSON(prefix, test.cfg); err != nil {
				log.Fatal(err)
			}
		} else {
			fmt.Printf("Set YAML user config for %q\n", prefix)
			if err := client.SetYAML(prefix, test.cfg); err != nil {
				log.Fatal(err)
			}
		}
	}

	// Get configs in various format.
	body, err := client.GetJSON("db1")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("JSON config for \"db1\":\n%s\n", body)

	body, err = client.GetYAML("db 2")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("YAML config for \"db 2\":\n%s\n", body)

	// List keys.
	keys, err := client.List()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Users: %q\n", keys)

	// Remove keys: the default one cannot be removed.
	err = client.Delete("")
	if err == nil {
		log.Fatal("expected error")
	}
	err = client.Delete("db 2")
	if err != nil {
		log.Fatal(err)
	}

	// List keys again.
	keys, err = client.List()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Users: %q\n", keys)

	// Output:
	// Set YAML user config for "db1"
	// Set JSON user config for "db 2"
	// Set JSON user config for "\xfe"
	// JSON config for "db1":
	// {
	//   "hashed_password": "******"
	// }
	// YAML config for "db 2":
	// hashed_password:
	// - 10
	// - 20
	//
	// Users: ["" "db 2" "db1" "\xfe"]
	// Users: ["" "db1" "\xfe"]
}
Example #12
0
// Example_permission shows how to use the admin client to
// get/set/list/delete permission configs.
func Example_permission() {
	s := server.StartTestServer(nil)
	defer s.Stop()

	context := testutils.NewRootTestBaseContext()
	client := client.NewAdminClient(context, s.ServingAddr(), client.Permission)

	// The test server creates a permission config entry for 'server.TestUser'.
	// Delete it first so it does not interfere with our configs.
	err := client.Delete(server.TestUser)
	if err != nil {
		log.Fatal(err)
	}

	const yamlConfig = `
read: [readonly, readwrite]
write: [readwrite, writeonly]
`
	const jsonConfig = `{
	   "read": [
	     "readonly",
	     "readwrite"
	   ],
	   "write": [
	     "readwrite",
	     "writeonly"
	   ]
	 }`

	testData := []struct {
		prefix proto.Key
		cfg    string
		isJSON bool
	}{
		{proto.KeyMin, yamlConfig, false},
		{proto.Key("db1"), yamlConfig, false},
		{proto.Key("db 2"), jsonConfig, true},
		{proto.Key("\xfe"), jsonConfig, true},
	}

	// Write configs.
	for _, test := range testData {
		prefix := string(test.prefix)
		if test.isJSON {
			fmt.Printf("Set JSON permission config for %q\n", prefix)
			if err := client.SetJSON(prefix, test.cfg); err != nil {
				log.Fatal(err)
			}
		} else {
			fmt.Printf("Set YAML permission config for %q\n", prefix)
			if err := client.SetYAML(prefix, test.cfg); err != nil {
				log.Fatal(err)
			}
		}
	}

	// Get configs in various format.
	body, err := client.GetJSON("db1")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("JSON config for \"db1\":\n%s\n", body)

	body, err = client.GetYAML("db 2")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("YAML config for \"db 2\":\n%s\n", body)

	// List keys.
	keys, err := client.List()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Permission prefixes: %q\n", keys)

	// Remove keys: the default one cannot be removed.
	err = client.Delete("")
	if err == nil {
		log.Fatal("expected error")
	}
	err = client.Delete("db 2")
	if err != nil {
		log.Fatal(err)
	}

	// List keys again.
	keys, err = client.List()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Permission prefixes: %q\n", keys)

	// Output:
	// Set YAML permission config for ""
	// Set YAML permission config for "db1"
	// Set JSON permission config for "db 2"
	// Set JSON permission config for "\xfe"
	// JSON config for "db1":
	// {
	//   "read": [
	//     "readonly",
	//     "readwrite"
	//   ],
	//   "write": [
	//     "readwrite",
	//     "writeonly"
	//   ]
	// }
	// YAML config for "db 2":
	// read:
	// - readonly
	// - readwrite
	// write:
	// - readwrite
	// - writeonly
	//
	// Permission prefixes: ["" "db 2" "db1" "\xfe"]
	// Permission prefixes: ["" "db1" "\xfe"]
}