Skip to content

Commit 4cb248c

Browse files
implemented deploy & verify
1 parent ff22fdf commit 4cb248c

6 files changed

Lines changed: 294 additions & 55 deletions

File tree

client/client.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,23 @@ type Client interface {
6767

6868
DeleteLinks(ctx context.Context, ids ...LinkId) error
6969

70+
// --- Deploy & Verify ---
71+
72+
DeployAccount(ctx context.Context, accountId AccountId) (chan DeployProgressAccount, error)
73+
74+
DeployAccounts(ctx context.Context, accountIds ...AccountId) (chan DeployProgressAccounts, error)
75+
76+
VerifyAccount(ctx context.Context, accountId AccountId) (chan VerifyProgressAccount, error)
77+
78+
VerifyAccounts(ctx context.Context, accountIds ...AccountId) (chan VerifyProgressAccounts, error)
79+
7080
// --- Other ---
7181

7282
ListExistingTags(ctx context.Context) tags.Tags
7383

7484
OnboardHost(ctx context.Context, host string, port int /* , gateway string, plugin string */, accountUsername string, deploymentKey string) (chan OnboardHostProgress, error)
7585

7686
DecommisionAccount(ctx context.Context, id AccountId) (chan DecommisionAccountProgress, error)
77-
78-
DeployAccount(ctx context.Context, accountId AccountId) (chan DeployProgressAccount, error)
79-
80-
DeployAccounts(ctx context.Context, accountIds ...AccountId) (chan DeployProgressAccounts, error)
8187
}
8288

8389
// id is a local identifier type used by the client API.
@@ -137,6 +143,9 @@ func (dp DeployProgressAccounts) Progress() float64 {
137143
) / float64(len(dp.Accounts))
138144
}
139145

146+
type VerifyProgressAccount = DeployProgressAccount
147+
type VerifyProgressAccounts = DeployProgressAccounts
148+
140149
// OnboardHostProgress reports progress during host onboarding.
141150
type OnboardHostProgress struct {
142151
Percent float64

client/mock/client.go

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,16 @@ type ClientOverwrites struct {
5151
UpdateLink func(ctx context.Context, id client.LinkId, accountId client.AccountId, tagMatcher string, expiresAt time.Time) error
5252
DeleteLinks func(ctx context.Context, ids ...client.LinkId) error
5353

54+
// --- Deploy & Verify ---
55+
DeployAccount func(ctx context.Context, accountId client.AccountId) (chan client.DeployProgressAccount, error)
56+
DeployAccounts func(ctx context.Context, accountIds ...client.AccountId) (chan client.DeployProgressAccounts, error)
57+
VerifyAccount func(ctx context.Context, accountId client.AccountId) (chan client.VerifyProgressAccount, error)
58+
VerifyAccounts func(ctx context.Context, accountIds ...client.AccountId) (chan client.VerifyProgressAccounts, error)
59+
5460
// --- Other ---
5561
ListExistingTags func(ctx context.Context) tags.Tags
5662
OnboardHost func(ctx context.Context, host string, port int /* , gateway string, plugin string */, accountUsername string, deploymentKey string) (chan client.OnboardHostProgress, error)
5763
DecommisionAccount func(ctx context.Context, id client.AccountId) (chan client.DecommisionAccountProgress, error)
58-
DeployAccount func(ctx context.Context, accountId client.AccountId) (chan client.DeployProgressAccount, error)
59-
DeployAccounts func(ctx context.Context, accountIds ...client.AccountId) (chan client.DeployProgressAccounts, error)
6064
}
6165

6266
// *[Client] implements [client.Client]
@@ -413,6 +417,56 @@ func (m *Client) DeleteLinks(ctx context.Context, ids ...client.LinkId) error {
413417
panic("Client.DeleteLinks not implemented")
414418
}
415419

420+
// --- Deploy & Verify ---
421+
422+
func (m *Client) DeployAccount(ctx context.Context, accountId client.AccountId) (chan client.DeployProgressAccount, error) {
423+
if m.Pre != nil {
424+
m.Pre("DeployAccount", map[string]any{"ctx": ctx, "accountId": accountId})
425+
}
426+
if m.Overwrites.DeployAccount != nil {
427+
return m.Overwrites.DeployAccount(ctx, accountId)
428+
} else if m.BaseClient != nil {
429+
return m.BaseClient.DeployAccount(ctx, accountId)
430+
}
431+
panic("Client.DeployAccount not implemented")
432+
}
433+
434+
func (m *Client) DeployAccounts(ctx context.Context, accountIds ...client.AccountId) (chan client.DeployProgressAccounts, error) {
435+
if m.Pre != nil {
436+
m.Pre("DeployAccounts", map[string]any{"ctx": ctx, "accountIds": accountIds})
437+
}
438+
if m.Overwrites.DeployAccounts != nil {
439+
return m.Overwrites.DeployAccounts(ctx, accountIds...)
440+
} else if m.BaseClient != nil {
441+
return m.BaseClient.DeployAccounts(ctx, accountIds...)
442+
}
443+
panic("Client.DeployAccounts not implemented")
444+
}
445+
446+
func (m *Client) VerifyAccount(ctx context.Context, accountId client.AccountId) (chan client.DeployProgressAccount, error) {
447+
if m.Pre != nil {
448+
m.Pre("VerifyAccount", map[string]any{"ctx": ctx, "accountId": accountId})
449+
}
450+
if m.Overwrites.VerifyAccount != nil {
451+
return m.Overwrites.VerifyAccount(ctx, accountId)
452+
} else if m.BaseClient != nil {
453+
return m.BaseClient.VerifyAccount(ctx, accountId)
454+
}
455+
panic("Client.VerifyAccount not implemented")
456+
}
457+
458+
func (m *Client) VerifyAccounts(ctx context.Context, accountIds ...client.AccountId) (chan client.VerifyProgressAccounts, error) {
459+
if m.Pre != nil {
460+
m.Pre("VerifyAccounts", map[string]any{"ctx": ctx, "accountIds": accountIds})
461+
}
462+
if m.Overwrites.VerifyAccounts != nil {
463+
return m.Overwrites.VerifyAccounts(ctx, accountIds...)
464+
} else if m.BaseClient != nil {
465+
return m.BaseClient.VerifyAccounts(ctx, accountIds...)
466+
}
467+
panic("Client.VerifyAccounts not implemented")
468+
}
469+
416470
// --- Other ---
417471

418472
func (m *Client) ListExistingTags(ctx context.Context) tags.Tags {
@@ -450,27 +504,3 @@ func (m *Client) DecommisionAccount(ctx context.Context, id client.AccountId) (c
450504
}
451505
panic("Client.DecommisionAccount not implemented")
452506
}
453-
454-
func (m *Client) DeployAccount(ctx context.Context, accountId client.AccountId) (chan client.DeployProgressAccount, error) {
455-
if m.Pre != nil {
456-
m.Pre("DeployAccount", map[string]any{"ctx": ctx, "accountId": accountId})
457-
}
458-
if m.Overwrites.DeployAccount != nil {
459-
return m.Overwrites.DeployAccount(ctx, accountId)
460-
} else if m.BaseClient != nil {
461-
return m.BaseClient.DeployAccount(ctx, accountId)
462-
}
463-
panic("Client.DeployAccount not implemented")
464-
}
465-
466-
func (m *Client) DeployAccounts(ctx context.Context, accountIds ...client.AccountId) (chan client.DeployProgressAccounts, error) {
467-
if m.Pre != nil {
468-
m.Pre("DeployAccounts", map[string]any{"ctx": ctx, "accountIds": accountIds})
469-
}
470-
if m.Overwrites.DeployAccounts != nil {
471-
return m.Overwrites.DeployAccounts(ctx, accountIds...)
472-
} else if m.BaseClient != nil {
473-
return m.BaseClient.DeployAccounts(ctx, accountIds...)
474-
}
475-
panic("Client.DeployAccounts not implemented")
476-
}

client/testui/client.go

Lines changed: 104 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -310,21 +310,7 @@ func (c *Client) DeleteLinks(ctx context.Context, ids ...client.LinkId) error {
310310
return nil
311311
}
312312

313-
// --- Other ---
314-
315-
func (c *Client) ListExistingTags(ctx context.Context) tags.Tags {
316-
return slicest.Reduce(c.publicKeys, func(publicKey client.PublicKey, tags tags.Tags) tags.Tags {
317-
return append(tags, publicKey.Tags...)
318-
})
319-
}
320-
321-
func (c *Client) OnboardHost(ctx context.Context, host string, port int /* , gateway string, plugin string */, accountUsername string, deploymentKey string) (chan client.OnboardHostProgress, error) {
322-
return nil, errors.New("client.OnboardHost not implemented")
323-
}
324-
325-
func (c *Client) DecommisionAccount(ctx context.Context, id client.AccountId) (chan client.DecommisionAccountProgress, error) {
326-
return nil, errors.New("client.DecommisionAccount not implemented")
327-
}
313+
// --- Deploy & Verify ---
328314

329315
func (c *Client) DeployAccount(ctx context.Context, accountId client.AccountId) (chan client.DeployProgressAccount, error) {
330316
dpc, err := c.DeployAccounts(ctx, accountId)
@@ -404,3 +390,106 @@ func (c *Client) DeployAccounts(ctx context.Context, accountIds ...client.Accoun
404390

405391
return deployProgressChan, nil
406392
}
393+
394+
func (c *Client) VerifyAccount(ctx context.Context, accountId client.AccountId) (chan client.VerifyProgressAccount, error) {
395+
dpc, err := c.VerifyAccounts(ctx, accountId)
396+
if err != nil {
397+
return nil, err
398+
}
399+
400+
// convert channel to only report the single accounts progress
401+
dbac := make(chan client.VerifyProgressAccount)
402+
go func() {
403+
defer close(dbac)
404+
405+
for dp := range dpc {
406+
dbac <- *dp.Accounts[accountId]
407+
}
408+
}()
409+
410+
return dbac, nil
411+
}
412+
413+
func (c *Client) VerifyAccounts(ctx context.Context, accountIds ...client.AccountId) (chan client.VerifyProgressAccounts, error) {
414+
accounts, err := c.GetAccounts(ctx, accountIds...)
415+
if err != nil {
416+
return nil, err
417+
}
418+
419+
deployDatas, err := slicest.MapX(accounts, func(a client.Account) (string, error) {
420+
return c.accountDeployData(ctx, a)
421+
})
422+
if err != nil {
423+
return nil, err
424+
}
425+
426+
verifyProgressChan := make(chan client.VerifyProgressAccounts)
427+
verifyProgress := client.VerifyProgressAccounts{
428+
Accounts: slicest.ToMap(accounts, func(account client.Account) (client.AccountId, *client.VerifyProgressAccount) {
429+
return account.Id, &client.VerifyProgressAccount{0, "not started", nil}
430+
}),
431+
}
432+
433+
go func() {
434+
defer close(verifyProgressChan)
435+
436+
for i, account := range accounts {
437+
verifyProgress.Accounts[account.Id].Status = "verifing"
438+
verifyProgressChan <- verifyProgress
439+
440+
// simulate deplay
441+
for _i := range 5 {
442+
time.Sleep(time.Millisecond * 100)
443+
verifyProgress.Accounts[account.Id].Progress = float64(_i+1) / 10
444+
verifyProgressChan <- verifyProgress
445+
}
446+
447+
_i, ok := slices.BinarySearchFunc(c.accounts, account.Id, func(a client.Account, id client.AccountId) int { return int(a.Id - id) })
448+
if !ok {
449+
verifyProgress.Accounts[account.Id].Status = "error"
450+
verifyProgress.Accounts[account.Id].Progress = 1
451+
verifyProgress.Accounts[account.Id].Err = fmt.Errorf("account with id %v not found", account.Id)
452+
verifyProgressChan <- verifyProgress
453+
continue
454+
}
455+
456+
// simulate deplay
457+
for _i := range 5 {
458+
time.Sleep(time.Millisecond * 100)
459+
verifyProgress.Accounts[account.Id].Progress = float64(_i+6) / 10
460+
verifyProgressChan <- verifyProgress
461+
}
462+
463+
// simulate getting deployCache from remote
464+
deployCache := c.accountDeployCache(account, deployDatas[i])
465+
466+
if c.accounts[_i].DeployCache != deployCache {
467+
verifyProgress.Accounts[account.Id].Status = "error"
468+
verifyProgress.Accounts[account.Id].Err = errors.New("account is out of sync")
469+
} else {
470+
verifyProgress.Accounts[account.Id].Status = "finished"
471+
}
472+
473+
verifyProgress.Accounts[account.Id].Progress = 1
474+
verifyProgressChan <- verifyProgress
475+
}
476+
}()
477+
478+
return verifyProgressChan, nil
479+
}
480+
481+
// --- Other ---
482+
483+
func (c *Client) ListExistingTags(ctx context.Context) tags.Tags {
484+
return slicest.Reduce(c.publicKeys, func(publicKey client.PublicKey, tags tags.Tags) tags.Tags {
485+
return append(tags, publicKey.Tags...)
486+
})
487+
}
488+
489+
func (c *Client) OnboardHost(ctx context.Context, host string, port int /* , gateway string, plugin string */, accountUsername string, deploymentKey string) (chan client.OnboardHostProgress, error) {
490+
return nil, errors.New("client.OnboardHost not implemented")
491+
}
492+
493+
func (c *Client) DecommisionAccount(ctx context.Context, id client.AccountId) (chan client.DecommisionAccountProgress, error) {
494+
return nil, errors.New("client.DecommisionAccount not implemented")
495+
}

ui/tui/models/helpers/deploy/deploy.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"strings"
1010

1111
tea "github.com/charmbracelet/bubbletea"
12+
"github.com/charmbracelet/lipgloss"
1213
"github.com/toeirei/keymaster/client"
1314
popupviews "github.com/toeirei/keymaster/ui/tui/models/views/popup"
1415
"github.com/toeirei/keymaster/util/slicest"
@@ -40,7 +41,9 @@ func DeployMany(ctx context.Context, c client.Client, accounts ...client.Account
4041
}
4142

4243
ids := slicest.Map(accounts, func(account client.Account) client.AccountId { return account.Id })
43-
accountsMap := slicest.ToMap(accounts, func(account client.Account) (client.AccountId, client.Account) { return account.Id, account })
44+
accountNamesMap := slicest.ToMap(accounts, func(account client.Account) (client.AccountId, string) { return account.Id, account.String() })
45+
accountNamesWidth := slicest.Reduce(slicest.MapValues(accountNamesMap), func(accountName string, width int) int { return max(width, len(accountName)) })
46+
accountNameRenderer := lipgloss.NewStyle().Width(accountNamesWidth)
4447

4548
dpc, err := c.DeployAccounts(ctx, ids...)
4649
if err != nil {
@@ -59,7 +62,7 @@ func DeployMany(ctx context.Context, c client.Client, accounts ...client.Account
5962
dp.Progress(),
6063
strings.Join(
6164
slicest.Map(ids, func(id client.AccountId) string {
62-
return fmt.Sprintf("%s - [%s]", accountsMap[id].String(), dp.Accounts[id].Status)
65+
return fmt.Sprintf("%s [%s]", accountNameRenderer.Render(accountNamesMap[id]), dp.Accounts[id].Status)
6366
}),
6467
"\n",
6568
),
@@ -76,9 +79,9 @@ func DeployMany(ctx context.Context, c client.Client, accounts ...client.Account
7679
strings.Join(
7780
slicest.Map(ids, func(id client.AccountId) string {
7881
if dp.Accounts[id].Err != nil {
79-
return fmt.Sprintf("%s: %s", accountsMap[id].String(), dp.Accounts[id].Err.Error())
82+
return fmt.Sprintf("%s %s", accountNameRenderer.Render(accountNamesMap[id]), dp.Accounts[id].Err.Error())
8083
}
81-
return fmt.Sprintf("%s: Success", accountsMap[id].String())
84+
return fmt.Sprintf("%s Success", accountNameRenderer.Render(accountNamesMap[id]))
8285
}),
8386
"\n",
8487
),

0 commit comments

Comments
 (0)