Skip to content

Commit

Permalink
Add environment update command (#235)
Browse files Browse the repository at this point in the history
* Add environment update command
  • Loading branch information
janelletavares authored Jan 6, 2022
1 parent 69b632e commit ba8117e
Show file tree
Hide file tree
Showing 16 changed files with 407 additions and 26 deletions.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ test:
docs:
rm -rf docs/cmd && mkdir -p docs/cmd/{md,www}
rm -rf etc && mkdir -p etc/man/man1 && mkdir -p etc/completion
go run gen-docs/main.go
go run gen-docs/main.go

.PHONY: lint
lint:
docker run --rm -v $(CURDIR):/app -w /app golangci/golangci-lint:latest golangci-lint run --timeout 5m -v
8 changes: 4 additions & 4 deletions cmd/meroxa/root/environments/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ type Describe struct {
logger log.Logger

args struct {
Name string
NameOrUUID string
}
}

func (d *Describe) Usage() string {
return "describe [NAME]"
return "describe [NAMEorUUID]"
}

func (d *Describe) Docs() builder.Docs {
Expand All @@ -59,7 +59,7 @@ func (d *Describe) Docs() builder.Docs {
}

func (d *Describe) Execute(ctx context.Context) error {
environment, err := d.client.GetEnvironment(ctx, d.args.Name)
environment, err := d.client.GetEnvironment(ctx, d.args.NameOrUUID)
if err != nil {
return err
}
Expand All @@ -83,6 +83,6 @@ func (d *Describe) ParseArgs(args []string) error {
return errors.New("requires environment name")
}

d.args.Name = args[0]
d.args.NameOrUUID = args[0]
return nil
}
6 changes: 3 additions & 3 deletions cmd/meroxa/root/environments/describe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ func TestDescribeEnvironmentArgs(t *testing.T) {
t.Fatalf("expected \"%s\" got \"%s\"", tt.err, err)
}

if tt.name != ar.args.Name {
t.Fatalf("expected \"%s\" got \"%s\"", tt.name, ar.args.Name)
if tt.name != ar.args.NameOrUUID {
t.Fatalf("expected \"%s\" got \"%s\"", tt.name, ar.args.NameOrUUID)
}
}
}
Expand All @@ -78,7 +78,7 @@ func TestDescribeEnvironmentExecution(t *testing.T) {
client: client,
logger: logger,
}
dc.args.Name = e.Name
dc.args.NameOrUUID = e.Name

err := dc.Execute(ctx)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions cmd/meroxa/root/environments/environments.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,6 @@ func (*Environments) SubCommands() []*cobra.Command {
builder.BuildCobraCommand(&Describe{}),
builder.BuildCobraCommand(&List{}),
builder.BuildCobraCommand(&Remove{}),
builder.BuildCobraCommand(&Update{}),
}
}
14 changes: 7 additions & 7 deletions cmd/meroxa/root/environments/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ type Remove struct {
logger log.Logger

args struct {
Name string
NameOrUUID string
}
}

func (r *Remove) Usage() string {
return "remove NAME"
return "remove NAMEorUUID"
}

func (r *Remove) Docs() builder.Docs {
Expand All @@ -59,18 +59,18 @@ func (r *Remove) Docs() builder.Docs {
}

func (r *Remove) ValueToConfirm(_ context.Context) (wantInput string) {
return r.args.Name
return r.args.NameOrUUID
}

func (r *Remove) Execute(ctx context.Context) error {
r.logger.Infof(ctx, "Environment %q is being removed...", r.args.Name)
r.logger.Infof(ctx, "Environment %q is being removed...", r.args.NameOrUUID)

e, err := r.client.DeleteEnvironment(ctx, r.args.Name)
e, err := r.client.DeleteEnvironment(ctx, r.args.NameOrUUID)
if err != nil {
return err
}

r.logger.Infof(ctx, "Run `meroxa env describe %s` for status.", r.args.Name)
r.logger.Infof(ctx, "Run `meroxa env describe %s` for status.", r.args.NameOrUUID)
r.logger.JSON(ctx, e)

return nil
Expand All @@ -89,7 +89,7 @@ func (r *Remove) ParseArgs(args []string) error {
return errors.New("requires environment name")
}

r.args.Name = args[0]
r.args.NameOrUUID = args[0]
return nil
}

Expand Down
6 changes: 3 additions & 3 deletions cmd/meroxa/root/environments/remove_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ func TestRemoveEnvironmentArgs(t *testing.T) {
t.Fatalf("expected \"%s\" got \"%s\"", tt.err, err)
}

if tt.name != cc.args.Name {
t.Fatalf("expected \"%s\" got \"%s\"", tt.name, cc.args.Name)
if tt.name != cc.args.NameOrUUID {
t.Fatalf("expected \"%s\" got \"%s\"", tt.name, cc.args.NameOrUUID)
}
}
}
Expand All @@ -69,7 +69,7 @@ func TestRemoveEnvironmentExecution(t *testing.T) {
}

e := utils.GenerateEnvironment("")
r.args.Name = e.Name
r.args.NameOrUUID = e.Name

client.
EXPECT().
Expand Down
227 changes: 227 additions & 0 deletions cmd/meroxa/root/environments/update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
/*
Copyright © 2021 Meroxa Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package environments

import (
"context"
"fmt"

"github.com/manifoldco/promptui"
"github.com/meroxa/cli/cmd/meroxa/builder"
"github.com/meroxa/cli/log"
"github.com/meroxa/meroxa-go/pkg/meroxa"
)

var (
_ builder.CommandWithDocs = (*Update)(nil)
_ builder.CommandWithArgs = (*Update)(nil)
_ builder.CommandWithFlags = (*Update)(nil)
_ builder.CommandWithClient = (*Update)(nil)
_ builder.CommandWithLogger = (*Update)(nil)
_ builder.CommandWithExecute = (*Update)(nil)
_ builder.CommandWithPrompt = (*Update)(nil)
)

type updateEnvironmentClient interface {
UpdateEnvironment(ctx context.Context, nameOrUUID string, body *meroxa.UpdateEnvironmentInput) (*meroxa.Environment, error)
}

type Update struct {
client updateEnvironmentClient
logger log.Logger

args struct {
NameOrUUID string
}

flags struct {
Name string `long:"name" usage:"updated environment name, when specified"`
Config []string `short:"c" long:"config" usage:"updated environment configuration based on type and provider (e.g.: --config aws_access_key_id=my_access_key --config aws_access_secret=my_access_secret)"` // nolint:lll
}

envCfg map[string]interface{}
}

func (c *Update) Logger(logger log.Logger) {
c.logger = logger
}

func (c *Update) Client(client meroxa.Client) {
c.client = client
}

func (c *Update) Flags() []builder.Flag {
return builder.BuildFlags(&c.flags)
}

func (c *Update) ParseArgs(args []string) error {
if len(args) > 0 {
c.args.NameOrUUID = args[0]
}
return nil
}

func (c *Update) SkipPrompt() bool {
return c.args.NameOrUUID != "" && c.flags.Name != "" && len(c.flags.Config) != 0
}

func (c *Update) setUserValues(e *meroxa.UpdateEnvironmentInput) {
if c.flags.Name != "" {
e.Name = c.flags.Name
}

if c.flags.Config != nil {
e.Configuration = stringSliceToMap(c.flags.Config)
}
}

func (c *Update) Execute(ctx context.Context) error {
e := &meroxa.UpdateEnvironmentInput{}
c.setUserValues(e)

// In case user skipped prompt and configuration was specified via flags
if len(c.flags.Config) != 0 {
e.Configuration = stringSliceToMap(c.flags.Config)
}
if c.flags.Name != "" {
e.Name = c.flags.Name
}

c.logger.Infof(ctx, "Updating environment...")

environment, err := c.client.UpdateEnvironment(ctx, c.args.NameOrUUID, e)

if err != nil {
return err
}

c.logger.Infof(ctx, "Environment %q has been updated. Run `meroxa env describe %s` for status", environment.Name, environment.Name)
c.logger.JSON(ctx, environment)

return nil
}

func (c *Update) NotConfirmed() string {
return "\nTo view all options for updating a Meroxa Environment,\n " +
"please run \"meroxa help env update\". \n"
}

func (c *Update) showEventConfirmation() {
var eventToConfirm string

eventToConfirm = "Environment details:\n"
eventToConfirm += fmt.Sprintf("\tCurrent Name or UUID: %s\n", c.args.NameOrUUID)
if c.flags.Name != "" {
eventToConfirm += fmt.Sprintf("\tNew Name: %s\n", c.flags.Name)
}

if len(c.envCfg) > 0 {
eventToConfirm += "\tNew Config:"

for k, v := range c.envCfg {
eventToConfirm += fmt.Sprintf("\n\t %s: %s", k, v)
}
}

fmt.Println(eventToConfirm)
}

func (c *Update) Prompt() error {
if c.args.NameOrUUID == "" {
p := promptui.Prompt{
Label: "Current Environment name or UUID",
Default: "",
}

c.args.NameOrUUID, _ = p.Run()
}

if c.flags.Name == "" {
p := promptui.Prompt{
Label: "New Environment name (optional)",
Default: "",
}

c.flags.Name, _ = p.Run()
}

c.envCfg = stringSliceToMap(c.flags.Config)
configPrompt := "a"
if len(c.flags.Config) != 0 {
configPrompt = "additional"
}

p := promptui.Prompt{
Label: fmt.Sprintf("Does your environment require %s new configuration", configPrompt),
IsConfirm: true,
}

_, err := p.Run()

// user responded "yes" to confirmation prompt
if err == nil {
cfgIsNeeded := true

for cfgIsNeeded {
p = promptui.Prompt{
Label: "Configuration key",
}

k, _ := p.Run()

p = promptui.Prompt{
Label: k,
}

v, _ := p.Run()
c.envCfg[k] = v

p := promptui.Prompt{
Label: "Add another configuration",
IsConfirm: true,
}

_, err = p.Run()
if err != nil {
cfgIsNeeded = false
}
}
}

c.showEventConfirmation()

prompt := promptui.Prompt{
Label: "Update this environment",
IsConfirm: true,
}

_, err = prompt.Run()
return err
}

func (c *Update) Usage() string {
return "update NAMEorUUID"
}

func (c *Update) Docs() builder.Docs {
return builder.Docs{
Short: "Update an environment",
Example: `
meroxa env update my-env --name new-name --config aws_access_key_id=my_access_key --config aws_access_secret=my_access_secret"
`,
}
}
Loading

0 comments on commit ba8117e

Please sign in to comment.