mirror of
https://github.com/1Password/onepassword-operator.git
synced 2025-10-22 23:48:05 +00:00

Connect has a delay when synchronizing files and returns a 500 error in this case, this function implements a retry mechanism. In this case we handle retries in the code and do not print redundunt errors in the POD logs.
104 lines
2.9 KiB
Go
104 lines
2.9 KiB
Go
package connect
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/1Password/connect-sdk-go/connect"
|
|
"github.com/1Password/connect-sdk-go/onepassword"
|
|
"github.com/1Password/onepassword-operator/pkg/onepassword/model"
|
|
)
|
|
|
|
// Config holds the configuration for the Connect client.
|
|
type Config struct {
|
|
ConnectHost string
|
|
ConnectToken string
|
|
}
|
|
|
|
// Connect is a client for interacting with 1Password using the Connect API.
|
|
type Connect struct {
|
|
client connect.Client
|
|
}
|
|
|
|
// NewClient creates a new Connect client using provided configuration.
|
|
func NewClient(config Config) *Connect {
|
|
return &Connect{
|
|
client: connect.NewClient(config.ConnectHost, config.ConnectToken),
|
|
}
|
|
}
|
|
|
|
func (c *Connect) GetItemByID(ctx context.Context, vaultID, itemID string) (*model.Item, error) {
|
|
connectItem, err := c.client.GetItemByUUID(itemID, vaultID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("GetItemByID 1Password Connect error: %w", err)
|
|
}
|
|
|
|
var item model.Item
|
|
item.FromConnectItem(connectItem)
|
|
return &item, nil
|
|
}
|
|
|
|
func (c *Connect) GetItemsByTitle(ctx context.Context, vaultID, itemTitle string) ([]model.Item, error) {
|
|
// Get all items in the vault with the specified title
|
|
connectItems, err := c.client.GetItemsByTitle(itemTitle, vaultID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("GetItemsByTitle 1Password Connect error: %w", err)
|
|
}
|
|
|
|
items := make([]model.Item, len(connectItems))
|
|
for i, connectItem := range connectItems {
|
|
var item model.Item
|
|
item.FromConnectItem(&connectItem)
|
|
items[i] = item
|
|
}
|
|
|
|
return items, nil
|
|
}
|
|
|
|
// GetFileContent retrieves the content of a file from a 1Password item.
|
|
// As the Connect has a delay when synchronizing files and returns a 500 error in this case, this function implements a retry mechanism.
|
|
func (c *Connect) GetFileContent(ctx context.Context, vaultID, itemID, fileID string) ([]byte, error) {
|
|
const maxRetries = 5
|
|
const delay = 1 * time.Second
|
|
|
|
var lastErr error
|
|
for i := 0; i < maxRetries; i++ {
|
|
bytes, err := c.client.GetFileContent(&onepassword.File{
|
|
ContentPath: fmt.Sprintf("/v1/vaults/%s/items/%s/files/%s/content", vaultID, itemID, fileID),
|
|
})
|
|
if err == nil {
|
|
return bytes, nil
|
|
}
|
|
|
|
var connectErr *onepassword.Error
|
|
if errors.As(err, &connectErr) && connectErr.StatusCode == 500 {
|
|
lastErr = err
|
|
time.Sleep(delay)
|
|
continue
|
|
}
|
|
|
|
return nil, fmt.Errorf("GetFileContent 1Password Connect error: %w", err)
|
|
}
|
|
|
|
return nil, fmt.Errorf("GetFileContent failed after retries: %w", lastErr)
|
|
}
|
|
|
|
func (c *Connect) GetVaultsByTitle(ctx context.Context, vaultQuery string) ([]model.Vault, error) {
|
|
connectVaults, err := c.client.GetVaultsByTitle(vaultQuery)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("GetVaultsByTitle 1Password Connect error: %w", err)
|
|
}
|
|
|
|
var vaults []model.Vault
|
|
for _, connectVault := range connectVaults {
|
|
if vaultQuery == connectVault.Name {
|
|
var vault model.Vault
|
|
vault.FromConnectVault(&connectVault)
|
|
vaults = append(vaults, vault)
|
|
}
|
|
}
|
|
return vaults, nil
|
|
}
|