Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: namespace configuration #324

Merged
merged 12 commits into from
Nov 26, 2020
Prev Previous commit
Next Next commit
feat: add namespace migrate command
  • Loading branch information
zepatrik committed Nov 25, 2020
commit 11bccf3cdf95c0aa338b36d38194e07d1c592819
96 changes: 96 additions & 0 deletions cmd/namespace/migrate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package namespace

import (
"errors"
"fmt"
"github.com/ghodss/yaml"
"github.com/ory/keto/internal/driver"
"github.com/ory/keto/internal/namespace"
"github.com/ory/keto/internal/persistence"
"github.com/ory/x/cmdx"
"github.com/ory/x/flagx"
"github.com/ory/x/logrusx"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"io/ioutil"
)

func NewMigrateCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "migrate <namespaces-file.yml>",
Short: "Migrate a namespace up.",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
d := driver.NewDefaultDriver(logrusx.New("keto", "master"), "master", "local", "today")

n, err := getNamespace(cmd, args[0])
if err != nil {
return err
}

status, err := d.Registry().NamespaceManager().NamespaceStatus(n)
if err != nil {
if !errors.Is(err, persistence.ErrNamespaceUnknown) {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not get status for namespace \"%s\": %+v\n", n.Name, err)
return cmdx.FailSilently(cmd)
}
} else {
if status.CurrentVersion == status.NextVersion {
_, _ = fmt.Fprintln(cmd.OutOrStdout(), "The namespace is already migrated up to the most recent version, there is noting to do.")
return nil
}

cmdx.PrintRow(cmd, status)

if !flagx.MustGetBool(cmd, YesFlag) {
if !cmdx.AskForConfirmation("Are you sure that you want to apply this migration? Make sure to check the CHANGELOG and UPGRADE for breaking changes beforehand.", cmd.InOrStdin(), cmd.OutOrStdout()) {
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "Migration of namespace \"%s\" aborted.\n", n.Name)
return nil
}
}
}

if err := d.Registry().NamespaceManager().MigrateNamespaceUp(n); err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not apply namespace migration: %+v\n", err)
return cmdx.FailSilently(cmd)
}

status, err = d.Registry().NamespaceManager().NamespaceStatus(n)
if err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not get status for namespace \"%s\": %+v\n", n.Name, err)
return cmdx.FailSilently(cmd)
}

cmdx.PrintRow(cmd, status)

return nil
},
}

registerYesFlag(cmd.Flags())
registerPackageFlags(cmd.Flags())

return cmd
}

const YesFlag = "yes"

func registerYesFlag(flags *pflag.FlagSet) {
flags.BoolP(YesFlag, YesFlag[:1], false, "answer all questions with yes")
}

func getNamespace(cmd *cobra.Command, fn string) (*namespace.Namespace, error) {
fc, err := ioutil.ReadFile(fn)
if err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not read file \"%s\": %+v\n", fn, err)
return nil, cmdx.FailSilently(cmd)
}

var n namespace.Namespace
if err := yaml.Unmarshal(fc, &n); err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not parse namespace from \"%s\": %+v\n", fn, err)
return nil, cmdx.FailSilently(cmd)
}

return &n, err
}
26 changes: 26 additions & 0 deletions cmd/namespace/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package namespace

import (
"github.com/ory/keto/cmd/client"
"github.com/ory/x/cmdx"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)

func NewNamespaceCmd() *cobra.Command {
return &cobra.Command{
Use: "namespace",
}
}

func RegisterCommandsRecursive(parent *cobra.Command) {
rootCmd := NewNamespaceCmd()
rootCmd.AddCommand(NewMigrateCmd())

parent.AddCommand(rootCmd)
}

func registerPackageFlags(flags *pflag.FlagSet) {
client.RegisterRemoteURLFlag(flags)
cmdx.RegisterFormatFlags(flags)
}
7 changes: 7 additions & 0 deletions cmd/namespace/validate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package namespace

import "github.com/spf13/cobra"

func NewValidateCmd() *cobra.Command {

}
6 changes: 3 additions & 3 deletions cmd/relationtuple/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
const (
FlagSubject = "subject"
FlagRelation = "relation"
FlagObject = "object"
FlagObject = "object"
FlagNamespace = "namespace"
)

Expand All @@ -39,8 +39,8 @@ func readQueryFromFlags(cmd *cobra.Command) (*acl.ListRelationTuplesRequest_Quer
namespace := flagx.MustGetString(cmd, FlagNamespace)

query := &acl.ListRelationTuplesRequest_Query{
Relation: relation,
Object: object,
Relation: relation,
Object: object,
Namespace: namespace,
}

Expand Down
9 changes: 8 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
package cmd

import (
"errors"
"fmt"
"github.com/ory/keto/cmd/namespace"
"github.com/ory/x/cmdx"
"os"
"path/filepath"
"runtime"
Expand Down Expand Up @@ -49,7 +52,9 @@ var logger = new(logrusx.Logger)
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
if !errors.Is(err, cmdx.ErrNoPrintButFail) {
fmt.Println(err)
}
os.Exit(-1)
}
}
Expand All @@ -67,6 +72,8 @@ func init() {
RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")

relationtuple.RegisterCommandRecursive(RootCmd)

namespace.RegisterCommandsRecursive(RootCmd)
}

// initConfig reads in config file and ENV variables if set.
Expand Down
2 changes: 1 addition & 1 deletion internal/driver/registry_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (r *RegistryDefault) Init() error {
continue
}

r.l.Infof("Namespace %s is migrated to version %d.", n.Name, s.Version)
r.l.Infof("Namespace %s is migrated to version %d.", n.Name, s.CurrentVersion)
}

return nil
Expand Down
29 changes: 27 additions & 2 deletions internal/namespace/definitons.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package namespace

import "encoding/json"
import (
"encoding/json"
"fmt"
"github.com/ory/x/cmdx"
)

type (
Namespace struct {
Expand All @@ -9,7 +13,8 @@ type (
Config json.RawMessage
}
Status struct {
Version int `db:"version"`
CurrentVersion int `json:"current_version" db:"version"`
NextVersion int `json:"next_version" db:"-"`
}
Manager interface {
MigrateNamespaceUp(n *Namespace) error
Expand All @@ -19,3 +24,23 @@ type (
NamespaceManager() Manager
}
)

var _ cmdx.OutputEntry = &Status{}

func (s *Status) Header() []string {
return []string{
"CURRENT VERSION",
"NEXT VERSION",
}
}

func (s *Status) Fields() []string {
return []string{
fmt.Sprintf("%d", s.CurrentVersion),
fmt.Sprintf("%d", s.NextVersion),
}
}

func (s *Status) Interface() interface{} {
return s
}
5 changes: 5 additions & 0 deletions internal/persistence/definitions.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package persistence

import (
"errors"
"github.com/ory/keto/internal/namespace"
"github.com/ory/keto/internal/relationtuple"
)
Expand All @@ -9,3 +10,7 @@ type Persister interface {
relationtuple.Manager
namespace.Manager
}

var (
ErrNamespaceUnknown = errors.New("namespace unknown")
)
7 changes: 1 addition & 6 deletions internal/persistence/memory/definitions.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
package memory

import (
"errors"
"sync"

"github.com/ory/keto/internal/namespace"

"github.com/ory/keto/internal/relationtuple"
)

const mostRecentNamespaceVersion = 0

var (
ErrNamespaceUnknown = errors.New("namespace unknown")
)
const mostRecentNamespaceVersion = 1

type Persister struct {
sync.RWMutex
Expand Down
12 changes: 8 additions & 4 deletions internal/persistence/memory/namespace.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package memory

import "github.com/ory/keto/internal/namespace"
import (
"github.com/ory/keto/internal/namespace"
"github.com/ory/keto/internal/persistence"
)

var _ namespace.Manager = &Persister{}

Expand All @@ -16,8 +19,8 @@ func (p *Persister) MigrateNamespaceUp(n *namespace.Namespace) error {
p.namespaces[n.Name] = &nc
}

if currStatus.Version < mostRecentNamespaceVersion {
currStatus.Version = mostRecentNamespaceVersion
if currStatus.CurrentVersion < mostRecentNamespaceVersion {
currStatus.CurrentVersion = mostRecentNamespaceVersion
}

return nil
Expand All @@ -29,9 +32,10 @@ func (p *Persister) NamespaceStatus(n *namespace.Namespace) (*namespace.Status,

s, ok := p.namespacesStatus[n.ID]
if !ok {
return nil, ErrNamespaceUnknown
return nil, persistence.ErrNamespaceUnknown
}

sc := *s
sc.NextVersion = mostRecentNamespaceVersion
return &sc, nil
}
5 changes: 3 additions & 2 deletions internal/persistence/memory/relationtuples.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package memory
import (
"context"
"fmt"
"github.com/ory/keto/internal/persistence"
"strconv"

"github.com/ory/keto/internal/x"
Expand Down Expand Up @@ -87,7 +88,7 @@ func (p *Persister) GetRelationTuples(_ context.Context, query *relationtuple.Re

n, ok := p.namespaces[query.Namespace]
if !ok {
return nil, "-1", ErrNamespaceUnknown
return nil, "-1", persistence.ErrNamespaceUnknown
}

var res []*relationtuple.InternalRelationTuple
Expand All @@ -108,7 +109,7 @@ func (p *Persister) WriteRelationTuples(_ context.Context, rs ...*relationtuple.
for _, r := range rs {
n, ok := p.namespaces[r.Namespace]
if !ok {
return ErrNamespaceUnknown
return persistence.ErrNamespaceUnknown
}

p.relations[n.ID] = append(p.relations[n.ID], r)
Expand Down
4 changes: 2 additions & 2 deletions internal/relationtuple/definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ func (r *InternalRelationTuple) String() string {
func (r *InternalRelationTuple) DeriveSubject() Subject {
return &SubjectSet{
Namespace: r.Namespace,
Object: r.Object,
Relation: r.Relation,
Object: r.Object,
Relation: r.Relation,
}
}

Expand Down