-
-
Notifications
You must be signed in to change notification settings - Fork 347
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: namespace configuration (#324)
- Loading branch information
Showing
25 changed files
with
675 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema#", | ||
"type": "object", | ||
"properties": { | ||
"name": { | ||
"type": "string", | ||
"title": "The name of the namespace.", | ||
"examples": [ | ||
"videos", | ||
"groups", | ||
"files" | ||
] | ||
}, | ||
"id": { | ||
"type": "integer", | ||
"title": "The unique ID of the namespace. Can not be changed once set.", | ||
"minimum": 0 | ||
}, | ||
"config": { | ||
"type": "object", | ||
"title": "The configuration of the namespace.", | ||
"description": "To be defined." | ||
} | ||
}, | ||
"required": [ | ||
"name", | ||
"id" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package namespace | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/ory/x/cmdx" | ||
"github.com/ory/x/flagx" | ||
"github.com/ory/x/logrusx" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/pflag" | ||
|
||
"github.com/ory/keto/internal/driver" | ||
"github.com/ory/keto/internal/persistence" | ||
) | ||
|
||
func NewMigrateCmd() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "migrate <namespaces.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 := validateNamespaceFile(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") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package namespace | ||
|
||
import ( | ||
"github.com/ory/x/cmdx" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/pflag" | ||
|
||
"github.com/ory/keto/cmd/client" | ||
) | ||
|
||
func NewNamespaceCmd() *cobra.Command { | ||
return &cobra.Command{ | ||
Use: "namespace", | ||
} | ||
} | ||
|
||
func RegisterCommandsRecursive(parent *cobra.Command) { | ||
rootCmd := NewNamespaceCmd() | ||
rootCmd.AddCommand(NewMigrateCmd(), NewValidateCmd()) | ||
|
||
parent.AddCommand(rootCmd) | ||
} | ||
|
||
func registerPackageFlags(flags *pflag.FlagSet) { | ||
client.RegisterRemoteURLFlag(flags) | ||
cmdx.RegisterFormatFlags(flags) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package namespace | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
|
||
"github.com/markbates/pkger" | ||
"github.com/ory/jsonschema/v3" | ||
"github.com/ory/x/cmdx" | ||
"github.com/ory/x/viperx" | ||
"github.com/segmentio/objconv/yaml" | ||
"github.com/spf13/cobra" | ||
|
||
"github.com/ory/keto/internal/namespace" | ||
) | ||
|
||
const namespaceSchemaPath = "/.schema/namespace.schema.json" | ||
|
||
func NewValidateCmd() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "validate <namespace.yml> [<namespace2.yml> ...]", | ||
Args: cobra.MinimumNArgs(1), | ||
Short: "Validate a namespace file.", | ||
Long: "Validate a namespace file and get human readable errors.", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
for _, fn := range args { | ||
_, err := validateNamespaceFile(cmd, fn) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), "Congrats, all files are valid!") | ||
return nil | ||
}, | ||
} | ||
|
||
return cmd | ||
} | ||
|
||
var namespaceSchema *jsonschema.Schema | ||
|
||
func validateNamespaceFile(cmd *cobra.Command, fn string) (*namespace.Namespace, error) { | ||
if namespaceSchema == nil { | ||
sf, err := pkger.Open(namespaceSchemaPath) | ||
if err != nil { | ||
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not open the namespace schema file. This is an internal error that should be reported. Thanks ;)\n%+v\n", err) | ||
return nil, cmdx.FailSilently(cmd) | ||
} | ||
|
||
c := jsonschema.NewCompiler() | ||
if err := c.AddResource(namespaceSchemaPath, sf); err != nil { | ||
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not add the namespace schema file to the compiler. This is an internal error that should be reported. Thanks ;)\n%+v\n", err) | ||
return nil, cmdx.FailSilently(cmd) | ||
} | ||
|
||
namespaceSchema, err = c.Compile(namespaceSchemaPath) | ||
if err != nil { | ||
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Could not compile the namespace schema file. This is an internal error that should be reported. Thanks ;)\n%+v\n", err) | ||
return nil, cmdx.FailSilently(cmd) | ||
} | ||
} | ||
|
||
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 val map[string]interface{} | ||
if err := yaml.Unmarshal(fc, &val); err != nil { | ||
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Encountered yaml unmarshal error for \"%s\": %+v\n", fn, err) | ||
return nil, cmdx.FailSilently(cmd) | ||
} | ||
|
||
if err := namespaceSchema.ValidateInterface(val); err != nil { | ||
viperx.PrintHumanReadableValidationErrors(cmd.ErrOrStderr(), err) | ||
return nil, cmdx.FailSilently(cmd) | ||
} | ||
|
||
var n namespace.Namespace | ||
if err := yaml.Unmarshal(fc, &n); err != nil { | ||
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Encountered yaml unmarshal error for \"%s\": %+v\n", fn, err) | ||
return nil, cmdx.FailSilently(cmd) | ||
} | ||
|
||
return &n, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.