Skip to content

Commit

Permalink
Archive and Update project command (flyteorg#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
pmahindrakar-oss authored and robert-ulbrich-mercedes-benz committed Jul 2, 2024
1 parent e8eb060 commit 3ff8060
Show file tree
Hide file tree
Showing 8 changed files with 424 additions and 3 deletions.
2 changes: 2 additions & 0 deletions flytectl/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"context"
"fmt"
"github.com/lyft/flytectl/cmd/update"
"github.com/lyft/flytectl/cmd/register"

"github.com/lyft/flytectl/cmd/get"
Expand Down Expand Up @@ -38,6 +39,7 @@ func newRootCmd() *cobra.Command {
rootCmd.AddCommand(viper.GetConfigCommand())
rootCmd.AddCommand(versionCmd)
rootCmd.AddCommand(get.CreateGetCommand())
rootCmd.AddCommand(update.CreateUpdateCommand())
rootCmd.AddCommand(register.RegisterCommand())
config.GetConfig()

Expand Down
52 changes: 52 additions & 0 deletions flytectl/cmd/update/project.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package update

import (
"context"
"fmt"
"github.com/lyft/flytectl/cmd/config"
cmdCore "github.com/lyft/flytectl/cmd/core"
"github.com/lyft/flyteidl/gen/pb-go/flyteidl/admin"
)

//go:generate pflags ProjectConfig

// Config hold configuration for project update flags.
type ProjectConfig struct {
ActivateProject bool `json:"activateProject" pflag:",Activates the project specified as argument."`
ArchiveProject bool `json:"archiveProject" pflag:",Archives the project specified as argument."`
}

var (
projectConfig = &ProjectConfig{}
errProjectNotFound = "Project %v not found\n"
errInvalidUpdate = "Invalid state passed. Specify either activate or archive\n"
errFailedUpdate = "Project %v failed to get updated to %v state due to %v\n"
)

func updateProjectsFunc(ctx context.Context, args []string, cmdCtx cmdCore.CommandContext) error {
id := config.GetConfig().Project
if id == "" {
fmt.Printf(errProjectNotFound, id)
return nil
}
archiveProject := projectConfig.ArchiveProject
activateProject := projectConfig.ActivateProject
if activateProject == archiveProject {
fmt.Printf(errInvalidUpdate)
return nil
}
projectState := admin.Project_ACTIVE
if archiveProject {
projectState = admin.Project_ARCHIVED
}
_, err := cmdCtx.AdminClient().UpdateProject(ctx, &admin.Project{
Id: id,
State: projectState,
})
if err != nil {
fmt.Printf(errFailedUpdate, id, projectState, err)
return nil
}
fmt.Printf("Project %v updated to %v state\n", id, projectState)
return nil
}
130 changes: 130 additions & 0 deletions flytectl/cmd/update/project_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package update

import (
"bytes"
"context"
"errors"
"github.com/lyft/flytectl/cmd/config"
cmdCore "github.com/lyft/flytectl/cmd/core"
"github.com/lyft/flyteidl/clients/go/admin/mocks"
"github.com/lyft/flyteidl/gen/pb-go/flyteidl/admin"
"github.com/stretchr/testify/assert"
"io"
"log"
"os"
"testing"
)

const projectValue = "dummyProject"

var (
reader *os.File
writer *os.File
err error
ctx context.Context
mockClient *mocks.AdminServiceClient
mockOutStream io.Writer
args []string
cmdCtx cmdCore.CommandContext
projectUpdateRequest *admin.Project
stdOut *os.File
stderr *os.File
)

func setup() {
reader, writer, err = os.Pipe()
if err != nil {
panic(err)
}
stdOut = os.Stdout
stderr = os.Stderr
os.Stdout = writer
os.Stderr = writer
log.SetOutput(writer)
config.GetConfig().Project = projectValue
mockClient = new(mocks.AdminServiceClient)
mockOutStream = writer
cmdCtx = cmdCore.NewCommandContext(mockClient, mockOutStream)
projectUpdateRequest = &admin.Project{
Id: projectValue,
State: admin.Project_ACTIVE,
}
}

func teardownAndVerify(t *testing.T, expectedLog string) {
writer.Close()
os.Stdout = stdOut
os.Stderr = stderr
var buf bytes.Buffer
io.Copy(&buf, reader)
assert.Equal(t, expectedLog, buf.String())
}

func modifyProjectFlags(archiveProject *bool, newArchiveVal bool, activateProject *bool, newActivateVal bool) {
*archiveProject = newArchiveVal
*activateProject = newActivateVal
}

func TestActivateProjectFunc(t *testing.T) {
setup()
defer teardownAndVerify(t, "Project dummyProject updated to ACTIVE state\n")
modifyProjectFlags(&(projectConfig.ArchiveProject), false, &(projectConfig.ActivateProject), true)
mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, nil)
updateProjectsFunc(ctx, args, cmdCtx)
mockClient.AssertCalled(t, "UpdateProject", ctx, projectUpdateRequest)
}

func TestActivateProjectFuncWithError(t *testing.T) {
setup()
defer teardownAndVerify(t, "Project dummyProject failed to get updated to ACTIVE state due to Error Updating Project\n")
modifyProjectFlags(&(projectConfig.ArchiveProject), false, &(projectConfig.ActivateProject), true)
mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, errors.New("Error Updating Project"))
updateProjectsFunc(ctx, args, cmdCtx)
mockClient.AssertCalled(t, "UpdateProject", ctx, projectUpdateRequest)
}

func TestArchiveProjectFunc(t *testing.T) {
setup()
defer teardownAndVerify(t, "Project dummyProject updated to ARCHIVED state\n")
modifyProjectFlags(&(projectConfig.ArchiveProject), true, &(projectConfig.ActivateProject), false)
projectUpdateRequest := &admin.Project{
Id: projectValue,
State: admin.Project_ARCHIVED,
}
mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, nil)
err := updateProjectsFunc(ctx, args, cmdCtx)
assert.Nil(t, err)
mockClient.AssertCalled(t, "UpdateProject", ctx, projectUpdateRequest)
}

func TestArchiveProjectFuncWithError(t *testing.T) {
setup()
defer teardownAndVerify(t, "Project dummyProject failed to get updated to ARCHIVED state due to Error Updating Project\n")
modifyProjectFlags(&(projectConfig.ArchiveProject), true, &(projectConfig.ActivateProject), false)
projectUpdateRequest := &admin.Project{
Id: projectValue,
State: admin.Project_ARCHIVED,
}
mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, errors.New("Error Updating Project"))
updateProjectsFunc(ctx, args, cmdCtx)
mockClient.AssertCalled(t, "UpdateProject", ctx, projectUpdateRequest)
}

func TestEmptyProjectInput(t *testing.T) {
setup()
defer teardownAndVerify(t, "Project not found\n")
config.GetConfig().Project = ""
modifyProjectFlags(&(projectConfig.ArchiveProject), false, &(projectConfig.ActivateProject), true)
mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, nil)
updateProjectsFunc(ctx, args, cmdCtx)
mockClient.AssertNotCalled(t, "UpdateProject", ctx, projectUpdateRequest)
}

func TestInvalidInput(t *testing.T) {
setup()
defer teardownAndVerify(t, "Invalid state passed. Specify either activate or archive\n")
modifyProjectFlags(&(projectConfig.ArchiveProject), false, &(projectConfig.ActivateProject), false)
mockClient.OnUpdateProjectMatch(ctx, projectUpdateRequest).Return(nil, nil)
updateProjectsFunc(ctx, args, cmdCtx)
mockClient.AssertNotCalled(t, "UpdateProject", ctx, projectUpdateRequest)
}
47 changes: 47 additions & 0 deletions flytectl/cmd/update/projectconfig_flags.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

146 changes: 146 additions & 0 deletions flytectl/cmd/update/projectconfig_flags_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 3ff8060

Please sign in to comment.