// v2KeysURL forms a URL representing the location of a key. // The endpoint argument represents the base URL of an etcd // server. The prefix is the path needed to route from the // provided endpoint's path to the root of the keys API // (typically "/v2/keys"). func v2KeysURL(ep url.URL, prefix, key string) *url.URL { // We concatenate all parts together manually. We cannot use // path.Join because it does not reserve trailing slash. // We call CanonicalURLPath to further cleanup the path. if prefix != "" && prefix[0] != '/' { prefix = "/" + prefix } if key != "" && key[0] != '/' { key = "/" + key } ep.Path = pathutil.CanonicalURLPath(ep.Path + prefix + key) return &ep }
func roleGrantRevoke(c *cli.Context, grant bool) { path := c.String("path") if path == "" { fmt.Fprintln(os.Stderr, "No path specified; please use `-path`") os.Exit(1) } if pathutil.CanonicalURLPath(path) != path { fmt.Fprintf(os.Stderr, "Not canonical path; please use `-path=%s`\n", pathutil.CanonicalURLPath(path)) os.Exit(1) } read := c.Bool("read") write := c.Bool("write") rw := c.Bool("readwrite") permcount := 0 for _, v := range []bool{read, write, rw} { if v { permcount++ } } if permcount != 1 { fmt.Fprintln(os.Stderr, "Please specify exactly one of -read, -write or -readwrite") os.Exit(1) } var permType client.PermissionType switch { case read: permType = client.ReadPermission case write: permType = client.WritePermission case rw: permType = client.ReadWritePermission } api, role := mustRoleAPIAndName(c) ctx, cancel := contextWithTotalTimeout(c) defer cancel() currentRole, err := api.GetRole(ctx, role) if err != nil { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(1) } var newRole *client.Role if grant { newRole, err = api.GrantRoleKV(ctx, role, []string{path}, permType) } else { newRole, err = api.RevokeRoleKV(ctx, role, []string{path}, permType) } if err != nil { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(1) } if reflect.DeepEqual(newRole, currentRole) { if grant { fmt.Printf("Role unchanged; already granted") } else { fmt.Printf("Role unchanged; already revoked") } } fmt.Printf("Role %s updated\n", role) }