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(cli): delete team locks #1903

Merged
merged 35 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3e243e2
removed flag
miguel-crespo-fdc Aug 22, 2024
33fe3f9
added delete env lock
miguel-crespo-fdc Aug 18, 2024
2986428
refactor
miguel-crespo-fdc Aug 18, 2024
ad2059a
refactor
miguel-crespo-fdc Aug 19, 2024
144701f
adapt tests
miguel-crespo-fdc Aug 22, 2024
4187a6e
removed completely
miguel-crespo-fdc Aug 22, 2024
9247282
remove dex auth
miguel-crespo-fdc Aug 22, 2024
40ecac5
final tests
miguel-crespo-fdc Aug 22, 2024
2aa0828
merge with main
miguel-crespo-fdc Aug 22, 2024
14cb2b8
added delete env lock
miguel-crespo-fdc Aug 18, 2024
35c4e7d
refactor
miguel-crespo-fdc Aug 19, 2024
b59925b
Added delete app locks
miguel-crespo-fdc Aug 18, 2024
aaca104
refactor
miguel-crespo-fdc Aug 19, 2024
9d15913
unit tests
miguel-crespo-fdc Aug 19, 2024
9160a79
unit tests
miguel-crespo-fdc Aug 19, 2024
83cc919
refactor
miguel-crespo-fdc Aug 22, 2024
d3e3424
create -> delete
miguel-crespo-fdc Aug 22, 2024
17fd276
remove httpmethod
miguel-crespo-fdc Aug 22, 2024
1f40afb
merge main
miguel-crespo-fdc Aug 22, 2024
177eb15
removed dex auth and change messages
miguel-crespo-fdc Aug 22, 2024
6eb7233
more messages
miguel-crespo-fdc Aug 22, 2024
f579f83
deleted executable
miguel-crespo-fdc Aug 22, 2024
29d8ae1
added delete env lock
miguel-crespo-fdc Aug 18, 2024
46b2d8e
refactor
miguel-crespo-fdc Aug 19, 2024
4292a3e
Added delete app locks
miguel-crespo-fdc Aug 18, 2024
b1c69cf
Delete team locks
miguel-crespo-fdc Aug 18, 2024
18ed4b3
Tests
miguel-crespo-fdc Aug 19, 2024
fc826ca
messages
miguel-crespo-fdc Aug 22, 2024
8cb1780
remove executable
miguel-crespo-fdc Aug 22, 2024
0a2339f
remove method
miguel-crespo-fdc Aug 22, 2024
d819258
env lock parsing
miguel-crespo-fdc Aug 22, 2024
a22c8ff
merge main
miguel-crespo-fdc Aug 22, 2024
2f94165
delete team locks
miguel-crespo-fdc Aug 22, 2024
8bbe147
team locks
miguel-crespo-fdc Aug 22, 2024
1caa534
tests
miguel-crespo-fdc Aug 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cli/pkg/cmd/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ func RunCLI() ReturnCode {
return handleDeleteEnvLock(*kpClientParams, subflags)
case "delete-app-lock":
return handleDeleteAppLock(*kpClientParams, subflags)
case "delete-team-lock":
return handleDeleteTeamLock(*kpClientParams, subflags)
default:
log.Printf("unknown subcommand %s\n", subcommand)
return ReturnCodeInvalidArguments
Expand Down
10 changes: 10 additions & 0 deletions cli/pkg/cmd/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@ func handleCreateAppLock(kpClientParams kuberpultClientParameters, args []string
return handleLockRequest(kpClientParams, parsedArgs)
}

func handleDeleteTeamLock(kpClientParams kuberpultClientParameters, args []string) ReturnCode {
parsedArgs, err := locks.ParseArgsDeleteTeamLock(args)

if err != nil {
log.Printf("error while parsing command line args, error: %v", err)
return ReturnCodeInvalidArguments
}
return handleLockRequest(kpClientParams, parsedArgs)
}

func handleCreateTeamLock(kpClientParams kuberpultClientParameters, args []string) ReturnCode {
parsedArgs, err := locks.ParseArgsCreateTeamLock(args)

Expand Down
32 changes: 27 additions & 5 deletions cli/pkg/locks/lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,21 @@ type DeleteAppLockParameters struct {
UseDexAuthentication bool
}

type TeamLockParameters struct {
type CreateTeamLockParameters struct {
Environment string
LockId string
Message string
Team string
UseDexAuthentication bool
}

type DeleteTeamLockParameters struct {
Environment string
LockId string
Team string
UseDexAuthentication bool
}

type EnvironmentGroupLockParameters struct {
EnvironmentGroup string
LockId string
Expand Down Expand Up @@ -167,16 +174,18 @@ func (e *DeleteAppLockParameters) FillHttpInfo() (*HttpInfo, error) {
}, nil
}

func (e *TeamLockParameters) FillHttpInfo() (*HttpInfo, error) {
func (e *CreateTeamLockParameters) FillHttpInfo() (*HttpInfo, error) {
d := LockJsonData{
Message: e.Message,
}
var jsonData, err = json.Marshal(d)
if err != nil {
return nil, fmt.Errorf("Could not marshal TeamLockParameters data to json: %w\n", err)
return nil, fmt.Errorf("Could not marshal CreateTeamLockParameters data to json: %w\n", err)
}
prefix := "environments"
if e.UseDexAuthentication {
prefix = "api/environments"
}

prefix := "api/environments"
return &HttpInfo{
jsonData: jsonData,
ContentType: "application/json",
Expand All @@ -185,6 +194,19 @@ func (e *TeamLockParameters) FillHttpInfo() (*HttpInfo, error) {
}, nil
}

func (e *DeleteTeamLockParameters) FillHttpInfo() (*HttpInfo, error) {
prefix := "environments"
if e.UseDexAuthentication {
prefix = "api/environments"
}
return &HttpInfo{
jsonData: []byte{},
ContentType: "application/json",
HttpMethod: http.MethodDelete,
RestPath: fmt.Sprintf("%s/%s/lock/team/%s/%s", prefix, e.Environment, e.Team, e.LockId),
}, nil
}

func (e *EnvironmentGroupLockParameters) FillHttpInfo() (*HttpInfo, error) {
d := LockJsonData{
Message: e.Message,
Expand Down
78 changes: 75 additions & 3 deletions cli/pkg/locks/team_lock_parsing.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func readCreateTeamLockArgs(args []string) (*CreateTeamLockCommandLineArguments,
fs.Var(&cmdArgs.lockId, "lockID", "the ID of the lock you are trying to create")
fs.Var(&cmdArgs.environment, "environment", "the environment to lock")
fs.Var(&cmdArgs.message, "message", "lock message")
fs.Var(&cmdArgs.team, "team", "application to lock")
fs.Var(&cmdArgs.team, "team", "team to lock")

if err := fs.Parse(args); err != nil {
return nil, fmt.Errorf("error while parsing command line arguments, error: %w", err)
Expand All @@ -80,11 +80,11 @@ func convertToCreateTeamLockParams(cmdArgs CreateTeamLockCommandLineArguments) (
return nil, fmt.Errorf("the provided command line arguments structure is invalid, cause: %s", msg)
}

rp := TeamLockParameters{
rp := CreateTeamLockParameters{
LockId: cmdArgs.lockId.Values[0],
Environment: cmdArgs.environment.Values[0],
Team: cmdArgs.team.Values[0],
UseDexAuthentication: false, //For now there is no ambiguity as to which endpoint to use
UseDexAuthentication: true, //For now there is no ambiguity as to which endpoint to use
Message: "",
}
if len(cmdArgs.message.Values) != 0 {
Expand All @@ -104,3 +104,75 @@ func ParseArgsCreateTeamLock(args []string) (LockParameters, error) {
}
return rp, nil
}

type DeleteTeamLockCommandLineArguments struct {
environment cli_utils.RepeatedString
lockId cli_utils.RepeatedString
team cli_utils.RepeatedString
}

func argsValidDeleteTeamLock(cmdArgs *DeleteTeamLockCommandLineArguments) (result bool, errorMessage string) {
if len(cmdArgs.lockId.Values) != 1 {
return false, "the --lockID arg must be set exactly once"
}
if len(cmdArgs.environment.Values) != 1 {
return false, "the --environment arg must be set exactly once"
}
if len(cmdArgs.team.Values) != 1 {
return false, "the --team arg must be set exactly once"
}

return true, ""
}

func readDeleteTeamLockArgs(args []string) (*DeleteTeamLockCommandLineArguments, error) {
cmdArgs := DeleteTeamLockCommandLineArguments{} //exhaustruct:ignore

fs := flag.NewFlagSet("flag set", flag.ContinueOnError)

fs.Var(&cmdArgs.lockId, "lockID", "the ID of the lock you are trying to delete")
fs.Var(&cmdArgs.environment, "environment", "the environment of the lock you are trying to delete")
fs.Var(&cmdArgs.team, "team", "the team of the lock you are trying to delete")

if err := fs.Parse(args); err != nil {
return nil, fmt.Errorf("error while parsing command line arguments, error: %w", err)
}

if len(fs.Args()) != 0 { // kuberpult-cli release does not accept any positional arguments, so this is an error
return nil, fmt.Errorf("these arguments are not recognized: \"%v\"", strings.Join(fs.Args(), " "))
}

if ok, msg := argsValidDeleteTeamLock(&cmdArgs); !ok {
return nil, fmt.Errorf(msg)
}

return &cmdArgs, nil
}

// converts the intermediate representation of the command line flags into the final structure containing parameters for the release endpoint
func convertToDeleteTeamLockParams(cmdArgs DeleteTeamLockCommandLineArguments) (LockParameters, error) {
if ok, msg := argsValidDeleteTeamLock(&cmdArgs); !ok {
// this should never happen, as the validation is already peformed by the readArgs function
return nil, fmt.Errorf("the provided command line arguments structure is invalid, cause: %s", msg)
}

rp := DeleteTeamLockParameters{
LockId: cmdArgs.lockId.Values[0],
Environment: cmdArgs.environment.Values[0],
Team: cmdArgs.team.Values[0],
UseDexAuthentication: true,
}
return &rp, nil
}

func ParseArgsDeleteTeamLock(args []string) (LockParameters, error) {
cmdArgs, err := readDeleteTeamLockArgs(args)
if err != nil {
return nil, fmt.Errorf("error while reading command line arguments for team lock, error: %w", err)
}
rp, err := convertToDeleteTeamLockParams(*cmdArgs)
if err != nil {
return nil, fmt.Errorf("error while creating parameters for deleting team lock, error: %w", err)
}
return rp, nil
}
179 changes: 164 additions & 15 deletions cli/pkg/locks/team_lock_parsing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,112 @@ func TestReadArgsTeamLock(t *testing.T) {
}
}

func TestReadArgsDeleteTeamLock(t *testing.T) {
type testCase struct {
name string
args []string
expectedCmdArgs *DeleteTeamLockCommandLineArguments
expectedError error
}

tcs := []testCase{
{
name: "some unrecognized positional arguments",
args: []string{"potato", "tomato"},
expectedError: errMatcher{
msg: "these arguments are not recognized: \"potato tomato\"",
},
},
{
name: "some flags that don't exist",
args: []string{"--environment", "development", "--potato", "tomato"},
expectedError: errMatcher{
msg: "error while parsing command line arguments, error: flag provided but not defined: -potato",
},
},
{
name: "nothing provided",
args: []string{},
expectedError: errMatcher{
msg: "the --lockID arg must be set exactly once",
},
},
{
name: "lockID is not provided",
args: []string{"--environment", "development", "--team", "my-team"},
expectedError: errMatcher{
msg: "the --lockID arg must be set exactly once",
},
},
{
name: "environment is not provided",
args: []string{"--team", "my-team", "--lockID", "my-lock"},
expectedError: errMatcher{
msg: "the --environment arg must be set exactly once",
},
},
{
name: "application is not provided",
args: []string{"--environment", "development", "--lockID", "my-lock"},
expectedError: errMatcher{
msg: "the --team arg must be set exactly once",
},
},
{
name: "only --lockID is properly provided but without --environment",
args: []string{"--lockID", "potato"},
expectedError: errMatcher{
msg: "the --environment arg must be set exactly once",
},
},
{
name: "delete does not accept message",
args: []string{"--environment", "development", "--team", "my-team", "--lockID", "my-lock", "--message", "message"},
expectedError: errMatcher{
msg: "error while parsing command line arguments, error: flag provided but not defined: -message",
},
},
{
name: "environment, lockID and application are are specified",
args: []string{"--environment", "development", "--team", "my-team", "--lockID", "my-lock"},
expectedCmdArgs: &DeleteTeamLockCommandLineArguments{
environment: cli_utils.RepeatedString{
Values: []string{
"development",
},
},
lockId: cli_utils.RepeatedString{
Values: []string{
"my-lock",
},
},
team: cli_utils.RepeatedString{
Values: []string{
"my-team",
},
},
},
},
}

for _, tc := range tcs {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

cmdArgs, err := readDeleteTeamLockArgs(tc.args)
// check errors
if diff := cmp.Diff(tc.expectedError, err, cmpopts.EquateErrors()); diff != "" {
t.Fatalf("error mismatch (-want, +got):\n%s", diff)
}

if diff := cmp.Diff(cmdArgs, tc.expectedCmdArgs, cmp.AllowUnexported(DeleteTeamLockCommandLineArguments{})); diff != "" {
t.Fatalf("expected args:\n %v\n, got:\n %v, diff:\n %s\n", tc.expectedCmdArgs, cmdArgs, diff)
}
})
}
}

func TestParseArgsCreateTeamLock(t *testing.T) {
type testCase struct {
name string
Expand All @@ -141,31 +247,34 @@ func TestParseArgsCreateTeamLock(t *testing.T) {
{
name: "with environment and lockID and message",
cmdArgs: []string{"--environment", "development", "--team", "my-team", "--lockID", "my-lock", "--message", "message"},
expectedParams: &TeamLockParameters{
Environment: "development",
LockId: "my-lock",
Message: "message",
Team: "my-team",
expectedParams: &CreateTeamLockParameters{
Environment: "development",
LockId: "my-lock",
Message: "message",
Team: "my-team",
UseDexAuthentication: true,
},
},
{
name: "with environment, app and lockID and no message",
cmdArgs: []string{"--environment", "development", "--team", "my-team", "--lockID", "my-lock"},
expectedParams: &TeamLockParameters{
Environment: "development",
LockId: "my-lock",
Message: "",
Team: "my-team",
expectedParams: &CreateTeamLockParameters{
Environment: "development",
LockId: "my-lock",
Message: "",
Team: "my-team",
UseDexAuthentication: true,
},
},
{
name: "with environment and lockID and multi word message message",
cmdArgs: []string{"--environment", "development", "--team", "my-team", "--lockID", "my-lock", "--message", "this is a very long message"},
expectedParams: &TeamLockParameters{
Environment: "development",
LockId: "my-lock",
Team: "my-team",
Message: "this is a very long message",
expectedParams: &CreateTeamLockParameters{
Environment: "development",
LockId: "my-lock",
Team: "my-team",
Message: "this is a very long message",
UseDexAuthentication: true,
},
},
}
Expand All @@ -188,3 +297,43 @@ func TestParseArgsCreateTeamLock(t *testing.T) {
})
}
}

func TestParseArgsDeleteTeamLock(t *testing.T) {
type testCase struct {
name string
cmdArgs []string
expectedParams LockParameters
expectedError error
}

tcs := []testCase{
{
name: "with environment and lockID and team",
cmdArgs: []string{"--environment", "development", "--team", "my-team", "--lockID", "my-lock"},
expectedParams: &DeleteTeamLockParameters{
Environment: "development",
LockId: "my-lock",
Team: "my-team",
UseDexAuthentication: true,
},
},
}

for _, tc := range tcs {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

params, err := ParseArgsDeleteTeamLock(tc.cmdArgs)
// check errors
if diff := cmp.Diff(tc.expectedError, err, cmpopts.EquateErrors()); diff != "" {
t.Fatalf("error mismatch (-want, +got):\n%s", diff)
}

// check result
if diff := cmp.Diff(tc.expectedParams, params); diff != "" {
t.Fatalf("expected args:\n %v\n, got:\n %v\n, diff:\n %s\n", tc.expectedParams, params, diff)
}
})
}
}
Loading