From 4d23deb1cfbbb1307ed441102b6e513d77fb3638 Mon Sep 17 00:00:00 2001 From: Brandon Shutter Date: Fri, 13 Sep 2024 14:02:46 -0600 Subject: [PATCH] feat(helper): add support for finding CARs by account alias and account number - Introduced `Alias` field to `kion.Account` and `kion.CAR` structs. - Updated tests to reflect the new `Alias` field in account and CAR mappings. - Added `FindCARByNameAndAccountNumber` and `FindCARByNameAndAlias` helper functions to search CARs using account number and alias respectively. - Enhanced test coverage for the new helper functions with various edge cases (finding CARs by account number and alias). --- lib/helper/helper_test.go | 48 ++++++++++---- lib/helper/transform_test.go | 117 +++++++++++++++++++++++++++++++---- 2 files changed, 139 insertions(+), 26 deletions(-) diff --git a/lib/helper/helper_test.go b/lib/helper/helper_test.go index 3cb4828..cfaf0fa 100644 --- a/lib/helper/helper_test.go +++ b/lib/helper/helper_test.go @@ -1,11 +1,13 @@ package helper import ( + "fmt" + "github.com/kionsoftware/kion-cli/lib/kion" "github.com/kionsoftware/kion-cli/lib/structs" ) -//////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// // // // Resources // // // @@ -30,12 +32,12 @@ var kionTestProjectsNames = []string{ } var kionTestAccounts = []kion.Account{ - {Email: "test1@kion.io", Name: "account one", Number: "111111111111", TypeID: 1, ID: 101, IncludeLinkedAccountSpend: true, LinkedAccountNumber: "", LinkedRole: "", PayerID: 101, ProjectID: 101, SkipAccessChecking: true, UseOrgAccountInfo: false}, - {Email: "test2@kion.io", Name: "account two", Number: "121212121212", TypeID: 2, ID: 102, IncludeLinkedAccountSpend: false, LinkedAccountNumber: "", LinkedRole: "", PayerID: 102, ProjectID: 102, SkipAccessChecking: true, UseOrgAccountInfo: false}, - {Email: "test3@kion.io", Name: "account three", Number: "131313131313", TypeID: 3, ID: 103, IncludeLinkedAccountSpend: true, LinkedAccountNumber: "000000000000", LinkedRole: "", PayerID: 103, ProjectID: 103, SkipAccessChecking: true, UseOrgAccountInfo: false}, - {Email: "test4@kion.io", Name: "account four", Number: "141414141414", TypeID: 4, ID: 104, IncludeLinkedAccountSpend: false, LinkedAccountNumber: "", LinkedRole: "", PayerID: 104, ProjectID: 104, SkipAccessChecking: true, UseOrgAccountInfo: false}, - {Email: "test5@kion.io", Name: "account five", Number: "151515151515", TypeID: 5, ID: 105, IncludeLinkedAccountSpend: false, LinkedAccountNumber: "", LinkedRole: "", PayerID: 105, ProjectID: 105, SkipAccessChecking: true, UseOrgAccountInfo: false}, - {Email: "test6@kion.io", Name: "account six", Number: "161616161616", TypeID: 6, ID: 106, IncludeLinkedAccountSpend: false, LinkedAccountNumber: "", LinkedRole: "", PayerID: 106, ProjectID: 106, SkipAccessChecking: true, UseOrgAccountInfo: true}, + {Email: "test1@kion.io", Name: "account one", Alias: "acct-one-alias", Number: "111111111111", TypeID: 1, ID: 101, IncludeLinkedAccountSpend: true, LinkedAccountNumber: "", LinkedRole: "", PayerID: 101, ProjectID: 101, SkipAccessChecking: true, UseOrgAccountInfo: false}, + {Email: "test2@kion.io", Name: "account two", Alias: "acct-two-alias", Number: "121212121212", TypeID: 2, ID: 102, IncludeLinkedAccountSpend: false, LinkedAccountNumber: "", LinkedRole: "", PayerID: 102, ProjectID: 102, SkipAccessChecking: true, UseOrgAccountInfo: false}, + {Email: "test3@kion.io", Name: "account three", Alias: "acct-three-alias", Number: "131313131313", TypeID: 3, ID: 103, IncludeLinkedAccountSpend: true, LinkedAccountNumber: "000000000000", LinkedRole: "", PayerID: 103, ProjectID: 103, SkipAccessChecking: true, UseOrgAccountInfo: false}, + {Email: "test4@kion.io", Name: "account four", Alias: "acct-four-alias", Number: "141414141414", TypeID: 4, ID: 104, IncludeLinkedAccountSpend: false, LinkedAccountNumber: "", LinkedRole: "", PayerID: 104, ProjectID: 104, SkipAccessChecking: true, UseOrgAccountInfo: false}, + {Email: "test5@kion.io", Name: "account five", Alias: "acct-five-alias", Number: "151515151515", TypeID: 5, ID: 105, IncludeLinkedAccountSpend: false, LinkedAccountNumber: "", LinkedRole: "", PayerID: 105, ProjectID: 105, SkipAccessChecking: true, UseOrgAccountInfo: false}, + {Email: "test6@kion.io", Name: "account six", Alias: "acct-six-alias", Number: "161616161616", TypeID: 6, ID: 106, IncludeLinkedAccountSpend: false, LinkedAccountNumber: "", LinkedRole: "", PayerID: 106, ProjectID: 106, SkipAccessChecking: true, UseOrgAccountInfo: true}, } var kionTestAccountsNames = []string{ @@ -48,12 +50,12 @@ var kionTestAccountsNames = []string{ } var kionTestCARs = []kion.CAR{ - {AccountID: 101, AccountNumber: "111111111111", AccountType: "aws", AccountTypeID: 1, AccountName: "account one", ApplyToAllAccounts: true, AwsIamPath: "some path", AwsIamRoleName: "role one", CloudAccessRoleType: "type", FutureAccounts: true, ID: 101, LongTermAccessKeys: false, Name: "car one", ProjectID: 101, ShortTermAccessKeys: true, WebAccess: true}, - {AccountID: 102, AccountNumber: "121212121212", AccountType: "aws", AccountTypeID: 2, AccountName: "account two", ApplyToAllAccounts: true, AwsIamPath: "some path", AwsIamRoleName: "role two", CloudAccessRoleType: "type", FutureAccounts: true, ID: 102, LongTermAccessKeys: false, Name: "car two", ProjectID: 102, ShortTermAccessKeys: true, WebAccess: true}, - {AccountID: 103, AccountNumber: "131313131313", AccountType: "aws", AccountTypeID: 3, AccountName: "account three", ApplyToAllAccounts: true, AwsIamPath: "some path", AwsIamRoleName: "role three", CloudAccessRoleType: "type", FutureAccounts: true, ID: 103, LongTermAccessKeys: false, Name: "car three", ProjectID: 103, ShortTermAccessKeys: true, WebAccess: true}, - {AccountID: 104, AccountNumber: "141414141414", AccountType: "aws", AccountTypeID: 4, AccountName: "account four", ApplyToAllAccounts: true, AwsIamPath: "some path", AwsIamRoleName: "role four", CloudAccessRoleType: "type", FutureAccounts: true, ID: 104, LongTermAccessKeys: false, Name: "car four", ProjectID: 104, ShortTermAccessKeys: true, WebAccess: true}, - {AccountID: 105, AccountNumber: "151515151515", AccountType: "aws", AccountTypeID: 5, AccountName: "account five", ApplyToAllAccounts: true, AwsIamPath: "some path", AwsIamRoleName: "role five", CloudAccessRoleType: "type", FutureAccounts: true, ID: 105, LongTermAccessKeys: false, Name: "car five", ProjectID: 105, ShortTermAccessKeys: true, WebAccess: true}, - {AccountID: 106, AccountNumber: "161616161616", AccountType: "aws", AccountTypeID: 6, AccountName: "account six", ApplyToAllAccounts: true, AwsIamPath: "some path", AwsIamRoleName: "role six", CloudAccessRoleType: "type", FutureAccounts: true, ID: 106, LongTermAccessKeys: false, Name: "car six", ProjectID: 106, ShortTermAccessKeys: true, WebAccess: true}, + {AccountID: 101, AccountNumber: "111111111111", AccountAlias: "acct-one-alias", AccountType: "aws", AccountTypeID: 1, AccountName: "account one", ApplyToAllAccounts: true, AwsIamPath: "some path", AwsIamRoleName: "role one", CloudAccessRoleType: "type", FutureAccounts: true, ID: 101, LongTermAccessKeys: false, Name: "car one", ProjectID: 101, ShortTermAccessKeys: true, WebAccess: true}, + {AccountID: 102, AccountNumber: "121212121212", AccountAlias: "acct-two-alias", AccountType: "aws", AccountTypeID: 2, AccountName: "account two", ApplyToAllAccounts: true, AwsIamPath: "some path", AwsIamRoleName: "role two", CloudAccessRoleType: "type", FutureAccounts: true, ID: 102, LongTermAccessKeys: false, Name: "car two", ProjectID: 102, ShortTermAccessKeys: true, WebAccess: true}, + {AccountID: 103, AccountNumber: "131313131313", AccountAlias: "acct-three-alias", AccountType: "aws", AccountTypeID: 3, AccountName: "account three", ApplyToAllAccounts: true, AwsIamPath: "some path", AwsIamRoleName: "role three", CloudAccessRoleType: "type", FutureAccounts: true, ID: 103, LongTermAccessKeys: false, Name: "car three", ProjectID: 103, ShortTermAccessKeys: true, WebAccess: true}, + {AccountID: 104, AccountNumber: "141414141414", AccountAlias: "acct-four-alias", AccountType: "aws", AccountTypeID: 4, AccountName: "account four", ApplyToAllAccounts: true, AwsIamPath: "some path", AwsIamRoleName: "role four", CloudAccessRoleType: "type", FutureAccounts: true, ID: 104, LongTermAccessKeys: false, Name: "car four", ProjectID: 104, ShortTermAccessKeys: true, WebAccess: true}, + {AccountID: 105, AccountNumber: "151515151515", AccountAlias: "acct-five-alias", AccountType: "aws", AccountTypeID: 5, AccountName: "account five", ApplyToAllAccounts: true, AwsIamPath: "some path", AwsIamRoleName: "role five", CloudAccessRoleType: "type", FutureAccounts: true, ID: 105, LongTermAccessKeys: false, Name: "car five", ProjectID: 105, ShortTermAccessKeys: true, WebAccess: true}, + {AccountID: 106, AccountNumber: "161616161616", AccountAlias: "acct-six-alias", AccountType: "aws", AccountTypeID: 6, AccountName: "account six", ApplyToAllAccounts: true, AwsIamPath: "some path", AwsIamRoleName: "role six", CloudAccessRoleType: "type", FutureAccounts: true, ID: 106, LongTermAccessKeys: false, Name: "car six", ProjectID: 106, ShortTermAccessKeys: true, WebAccess: true}, } var kionTestCARsNames = []string{ @@ -106,3 +108,23 @@ var kionTestFavoritesNames = []string{ // Helpers // // // //////////////////////////////////////////////////////////////////////////////// + +// FindCARByNameAndAccountNumber finds a CAR by name and account number. +func FindCARByNameAndAccountNumber(cars []kion.CAR, name string, accountNumber string) (*kion.CAR, error) { + for _, car := range cars { + if car.Name == name && car.AccountNumber == accountNumber { + return &car, nil + } + } + return nil, fmt.Errorf("cannot find cloud access role with name %v and account number %v", name, accountNumber) +} + +// FindCARByNameAndAlias finds a CAR by name and account alias. +func FindCARByNameAndAlias(cars []kion.CAR, name string, accountAlias string) (*kion.CAR, error) { + for _, car := range cars { + if car.Name == name && car.AccountAlias == accountAlias { + return &car, nil + } + } + return nil, fmt.Errorf("cannot find cloud access role with name %v and account alias %v", name, accountAlias) +} diff --git a/lib/helper/transform_test.go b/lib/helper/transform_test.go index a498fae..b7bad79 100644 --- a/lib/helper/transform_test.go +++ b/lib/helper/transform_test.go @@ -59,20 +59,20 @@ func TestMapAccounts(t *testing.T) { "Basic", kionTestAccounts, []string{ - fmt.Sprintf("%v (%v)", kionTestAccountsNames[4], kionTestAccounts[4].Number), - fmt.Sprintf("%v (%v)", kionTestAccountsNames[3], kionTestAccounts[3].Number), - fmt.Sprintf("%v (%v)", kionTestAccountsNames[0], kionTestAccounts[0].Number), - fmt.Sprintf("%v (%v)", kionTestAccountsNames[5], kionTestAccounts[5].Number), - fmt.Sprintf("%v (%v)", kionTestAccountsNames[2], kionTestAccounts[2].Number), - fmt.Sprintf("%v (%v)", kionTestAccountsNames[1], kionTestAccounts[1].Number), + fmt.Sprintf("%v [%v] (%v)", kionTestAccountsNames[4], kionTestAccounts[4].Alias, kionTestAccounts[4].Number), + fmt.Sprintf("%v [%v] (%v)", kionTestAccountsNames[3], kionTestAccounts[3].Alias, kionTestAccounts[3].Number), + fmt.Sprintf("%v [%v] (%v)", kionTestAccountsNames[0], kionTestAccounts[0].Alias, kionTestAccounts[0].Number), + fmt.Sprintf("%v [%v] (%v)", kionTestAccountsNames[5], kionTestAccounts[5].Alias, kionTestAccounts[5].Number), + fmt.Sprintf("%v [%v] (%v)", kionTestAccountsNames[2], kionTestAccounts[2].Alias, kionTestAccounts[2].Number), + fmt.Sprintf("%v [%v] (%v)", kionTestAccountsNames[1], kionTestAccounts[1].Alias, kionTestAccounts[1].Number), }, map[string]kion.Account{ - fmt.Sprintf("%v (%v)", kionTestAccountsNames[0], kionTestAccounts[0].Number): kionTestAccounts[0], - fmt.Sprintf("%v (%v)", kionTestAccountsNames[1], kionTestAccounts[1].Number): kionTestAccounts[1], - fmt.Sprintf("%v (%v)", kionTestAccountsNames[2], kionTestAccounts[2].Number): kionTestAccounts[2], - fmt.Sprintf("%v (%v)", kionTestAccountsNames[3], kionTestAccounts[3].Number): kionTestAccounts[3], - fmt.Sprintf("%v (%v)", kionTestAccountsNames[4], kionTestAccounts[4].Number): kionTestAccounts[4], - fmt.Sprintf("%v (%v)", kionTestAccountsNames[5], kionTestAccounts[5].Number): kionTestAccounts[5], + fmt.Sprintf("%v [%v] (%v)", kionTestAccountsNames[0], kionTestAccounts[0].Alias, kionTestAccounts[0].Number): kionTestAccounts[0], + fmt.Sprintf("%v [%v] (%v)", kionTestAccountsNames[1], kionTestAccounts[1].Alias, kionTestAccounts[1].Number): kionTestAccounts[1], + fmt.Sprintf("%v [%v] (%v)", kionTestAccountsNames[2], kionTestAccounts[2].Alias, kionTestAccounts[2].Number): kionTestAccounts[2], + fmt.Sprintf("%v [%v] (%v)", kionTestAccountsNames[3], kionTestAccounts[3].Alias, kionTestAccounts[3].Number): kionTestAccounts[3], + fmt.Sprintf("%v [%v] (%v)", kionTestAccountsNames[4], kionTestAccounts[4].Alias, kionTestAccounts[4].Number): kionTestAccounts[4], + fmt.Sprintf("%v [%v] (%v)", kionTestAccountsNames[5], kionTestAccounts[5].Alias, kionTestAccounts[5].Number): kionTestAccounts[5], }, }, } @@ -86,7 +86,6 @@ func TestMapAccounts(t *testing.T) { }) } } - func TestMapCAR(t *testing.T) { tests := []struct { name string @@ -240,3 +239,95 @@ func TestFindCARByName(t *testing.T) { }) } } + +// New tests for alias and account ID + +func TestFindCARByNameAndAccountNumber(t *testing.T) { + tests := []struct { + name string + carName string + accountNumber string + cars []kion.CAR + wantCAR *kion.CAR + wantErr error + }{ + { + "Find Match", + "car one", + "111111111111", + kionTestCARs, + &kionTestCARs[0], + nil, + }, + { + "Find No Match - Wrong Account Number", + "car one", + "999999999999", + kionTestCARs, + nil, + fmt.Errorf("cannot find cloud access role with name %v and account number %v", "car one", "999999999999"), + }, + { + "Find No Match - Wrong CAR Name", + "fake car", + "111111111111", + kionTestCARs, + nil, + fmt.Errorf("cannot find cloud access role with name %v and account number %v", "fake car", "111111111111"), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + car, err := FindCARByNameAndAccountNumber(test.cars, test.carName, test.accountNumber) + if !reflect.DeepEqual(test.wantCAR, car) || (err != nil && err.Error() != test.wantErr.Error()) { + t.Errorf("\ngot:\n %v\n %v\nwanted:\n %v\n %v", car, err, test.wantCAR, test.wantErr) + } + }) + } +} + +func TestFindCARByNameAndAlias(t *testing.T) { + tests := []struct { + name string + carName string + accountAlias string + cars []kion.CAR + wantCAR *kion.CAR + wantErr error + }{ + { + "Find Match", + "car two", + "acct-two-alias", + kionTestCARs, + &kionTestCARs[1], + nil, + }, + { + "Find No Match - Wrong Account Alias", + "car two", + "non-existent-alias", + kionTestCARs, + nil, + fmt.Errorf("cannot find cloud access role with name %v and account alias %v", "car two", "non-existent-alias"), + }, + { + "Find No Match - Wrong CAR Name", + "fake car", + "acct-two-alias", + kionTestCARs, + nil, + fmt.Errorf("cannot find cloud access role with name %v and account alias %v", "fake car", "acct-two-alias"), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + car, err := FindCARByNameAndAlias(test.cars, test.carName, test.accountAlias) + if !reflect.DeepEqual(test.wantCAR, car) || (err != nil && err.Error() != test.wantErr.Error()) { + t.Errorf("\ngot:\n %v\n %v\nwanted:\n %v\n %v", car, err, test.wantCAR, test.wantErr) + } + }) + } +}