mirror of
https://github.com/1Password/onepassword-operator.git
synced 2025-10-22 07:28:06 +00:00
Merge branch 'vzt/service-accounts-support' into vzt/fix-context
# Conflicts: # USAGEGUIDE.md # cmd/main.go # pkg/onepassword/client/client.go # pkg/onepassword/items.go
This commit is contained in:
@@ -3,9 +3,10 @@ package client
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
|
||||
"github.com/1Password/onepassword-operator/pkg/onepassword/client/connect"
|
||||
"github.com/1Password/onepassword-operator/pkg/onepassword/client/sdk"
|
||||
"github.com/1Password/onepassword-operator/pkg/onepassword/model"
|
||||
@@ -19,8 +20,13 @@ type Client interface {
|
||||
GetVaultsByTitle(ctx context.Context, title string) ([]model.Vault, error)
|
||||
}
|
||||
|
||||
// NewClient creates a new 1Password client based on the provided configuration.
|
||||
func NewClient(ctx context.Context, integrationVersion string) (Client, error) {
|
||||
type Config struct {
|
||||
Logger logr.Logger
|
||||
Version string
|
||||
}
|
||||
|
||||
// NewFromEnvironment creates a new 1Password client based on the provided configuration.
|
||||
func NewFromEnvironment(ctx context.Context, cfg Config) (Client, error) {
|
||||
connectHost, _ := os.LookupEnv("OP_CONNECT_HOST")
|
||||
connectToken, _ := os.LookupEnv("OP_CONNECT_TOKEN")
|
||||
serviceAccountToken, _ := os.LookupEnv("OP_SERVICE_ACCOUNT_TOKEN")
|
||||
@@ -30,16 +36,16 @@ func NewClient(ctx context.Context, integrationVersion string) (Client, error) {
|
||||
}
|
||||
|
||||
if serviceAccountToken != "" {
|
||||
fmt.Printf("Using Service Account Token")
|
||||
cfg.Logger.Info("Using Service Account Token")
|
||||
return sdk.NewClient(ctx, sdk.Config{
|
||||
ServiceAccountToken: serviceAccountToken,
|
||||
IntegrationName: "1password-operator",
|
||||
IntegrationVersion: integrationVersion,
|
||||
IntegrationVersion: cfg.Version,
|
||||
})
|
||||
}
|
||||
|
||||
if connectHost != "" && connectToken != "" {
|
||||
fmt.Printf("Using Connect")
|
||||
cfg.Logger.Info("Using 1Password Connect")
|
||||
return connect.NewClient(connect.Config{
|
||||
ConnectHost: connectHost,
|
||||
ConnectToken: connectToken,
|
||||
|
@@ -13,7 +13,6 @@ import (
|
||||
type Config struct {
|
||||
ConnectHost string
|
||||
ConnectToken string
|
||||
UserAgent string
|
||||
}
|
||||
|
||||
// Connect is a client for interacting with 1Password using the Connect API.
|
||||
@@ -31,7 +30,7 @@ func NewClient(config Config) *Connect {
|
||||
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("1password Connect error: %w", err)
|
||||
return nil, fmt.Errorf("1Password Connect error: %w", err)
|
||||
}
|
||||
|
||||
var item model.Item
|
||||
@@ -43,14 +42,14 @@ func (c *Connect) GetItemsByTitle(ctx context.Context, vaultID, itemTitle string
|
||||
// Get all items in the vault with the specified title
|
||||
connectItems, err := c.client.GetItemsByTitle(itemTitle, vaultID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("1password Connect error: %w", err)
|
||||
return nil, fmt.Errorf("1Password Connect error: %w", err)
|
||||
}
|
||||
|
||||
var items []model.Item
|
||||
for _, connectItem := range connectItems {
|
||||
items := make([]model.Item, len(connectItems))
|
||||
for i, connectItem := range connectItems {
|
||||
var item model.Item
|
||||
item.FromConnectItem(&connectItem)
|
||||
items = append(items, item)
|
||||
items[i] = item
|
||||
}
|
||||
|
||||
return items, nil
|
||||
@@ -61,7 +60,7 @@ func (c *Connect) GetFileContent(ctx context.Context, vaultID, itemID, fileID st
|
||||
ContentPath: fmt.Sprintf("/v1/vaults/%s/items/%s/files/%s/content", vaultID, itemID, fileID),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("1password Connect error: %w", err)
|
||||
return nil, fmt.Errorf("1Password Connect error: %w", err)
|
||||
}
|
||||
|
||||
return bytes, nil
|
||||
@@ -70,7 +69,7 @@ func (c *Connect) GetFileContent(ctx context.Context, vaultID, itemID, fileID st
|
||||
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("1password Connect error: %w", err)
|
||||
return nil, fmt.Errorf("1Password Connect error: %w", err)
|
||||
}
|
||||
|
||||
var vaults []model.Vault
|
||||
@@ -81,6 +80,5 @@ func (c *Connect) GetVaultsByTitle(ctx context.Context, vaultQuery string) ([]mo
|
||||
vaults = append(vaults, vault)
|
||||
}
|
||||
}
|
||||
|
||||
return vaults, nil
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@@ -160,6 +161,7 @@ func TestConnect_GetFileContent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnect_GetVaultsByTitle(t *testing.T) {
|
||||
now := time.Now()
|
||||
testCases := map[string]struct {
|
||||
mockClient func() *mock.ConnectClientMock
|
||||
check func(t *testing.T, vaults []model.Vault, err error)
|
||||
@@ -169,12 +171,14 @@ func TestConnect_GetVaultsByTitle(t *testing.T) {
|
||||
mockConnectClient := &mock.ConnectClientMock{}
|
||||
mockConnectClient.On("GetVaultsByTitle", VaultTitleEmployee).Return([]onepassword.Vault{
|
||||
{
|
||||
ID: "test-id",
|
||||
Name: VaultTitleEmployee,
|
||||
ID: "test-id",
|
||||
Name: VaultTitleEmployee,
|
||||
CreatedAt: now,
|
||||
},
|
||||
{
|
||||
ID: "test-id-2",
|
||||
Name: "Some other vault",
|
||||
ID: "test-id-2",
|
||||
Name: "Some other vault",
|
||||
CreatedAt: now,
|
||||
},
|
||||
}, nil)
|
||||
return mockConnectClient
|
||||
@@ -183,6 +187,7 @@ func TestConnect_GetVaultsByTitle(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Len(t, vaults, 1)
|
||||
require.Equal(t, "test-id", vaults[0].ID)
|
||||
require.Equal(t, now, vaults[0].CreatedAt)
|
||||
},
|
||||
},
|
||||
"should return a two vaults": {
|
||||
@@ -190,12 +195,14 @@ func TestConnect_GetVaultsByTitle(t *testing.T) {
|
||||
mockConnectClient := &mock.ConnectClientMock{}
|
||||
mockConnectClient.On("GetVaultsByTitle", VaultTitleEmployee).Return([]onepassword.Vault{
|
||||
{
|
||||
ID: "test-id",
|
||||
Name: VaultTitleEmployee,
|
||||
ID: "test-id",
|
||||
Name: VaultTitleEmployee,
|
||||
CreatedAt: now,
|
||||
},
|
||||
{
|
||||
ID: "test-id-2",
|
||||
Name: VaultTitleEmployee,
|
||||
ID: "test-id-2",
|
||||
Name: VaultTitleEmployee,
|
||||
CreatedAt: now,
|
||||
},
|
||||
}, nil)
|
||||
return mockConnectClient
|
||||
@@ -205,8 +212,10 @@ func TestConnect_GetVaultsByTitle(t *testing.T) {
|
||||
require.Len(t, vaults, 2)
|
||||
// Check the first vault
|
||||
require.Equal(t, "test-id", vaults[0].ID)
|
||||
require.Equal(t, now, vaults[0].CreatedAt)
|
||||
// Check the second vault
|
||||
require.Equal(t, "test-id-2", vaults[1].ID)
|
||||
require.Equal(t, now, vaults[1].CreatedAt)
|
||||
},
|
||||
},
|
||||
"should return an error": {
|
||||
|
@@ -26,7 +26,7 @@ func NewClient(ctx context.Context, config Config) (*SDK, error) {
|
||||
sdk.WithIntegrationInfo(config.IntegrationName, config.IntegrationVersion),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("1password sdk error: %w", err)
|
||||
return nil, fmt.Errorf("1Password sdk error: %w", err)
|
||||
}
|
||||
|
||||
return &SDK{
|
||||
@@ -37,7 +37,7 @@ func NewClient(ctx context.Context, config Config) (*SDK, error) {
|
||||
func (s *SDK) GetItemByID(ctx context.Context, vaultID, itemID string) (*model.Item, error) {
|
||||
sdkItem, err := s.client.Items().Get(ctx, vaultID, itemID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("1password sdk error: %w", err)
|
||||
return nil, fmt.Errorf("1Password sdk error: %w", err)
|
||||
}
|
||||
|
||||
var item model.Item
|
||||
@@ -49,7 +49,7 @@ func (s *SDK) GetItemsByTitle(ctx context.Context, vaultID, itemTitle string) ([
|
||||
// Get all items in the vault
|
||||
sdkItems, err := s.client.Items().List(ctx, vaultID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("1password sdk error: %w", err)
|
||||
return nil, fmt.Errorf("1Password sdk error: %w", err)
|
||||
}
|
||||
|
||||
// Filter items by title
|
||||
@@ -70,7 +70,7 @@ func (s *SDK) GetFileContent(ctx context.Context, vaultID, itemID, fileID string
|
||||
ID: fileID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("1password sdk error: %w", err)
|
||||
return nil, fmt.Errorf("1Password sdk error: %w", err)
|
||||
}
|
||||
|
||||
return bytes, nil
|
||||
@@ -80,7 +80,7 @@ func (s *SDK) GetVaultsByTitle(ctx context.Context, title string) ([]model.Vault
|
||||
// List all vaults
|
||||
sdkVaults, err := s.client.Vaults().List(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("1password sdk error: %w", err)
|
||||
return nil, fmt.Errorf("1Password sdk error: %w", err)
|
||||
}
|
||||
|
||||
// Filter vaults by title
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -23,7 +24,7 @@ func TestSDK_GetItemByID(t *testing.T) {
|
||||
mockItemAPI func() *clientmock.ItemAPIMock
|
||||
check func(t *testing.T, item *model.Item, err error)
|
||||
}{
|
||||
"should return a single vault": {
|
||||
"should return a single item": {
|
||||
mockItemAPI: func() *clientmock.ItemAPIMock {
|
||||
m := &clientmock.ItemAPIMock{}
|
||||
m.On("Get", context.Background(), "vault-id", "item-id").Return(*sdkItem, nil)
|
||||
@@ -103,6 +104,17 @@ func TestSDK_GetItemsByTitle(t *testing.T) {
|
||||
clienttesting.CheckSDKItemOverviewMapping(t, sdkItem2, &items[1])
|
||||
},
|
||||
},
|
||||
"should return empty list": {
|
||||
mockItemAPI: func() *clientmock.ItemAPIMock {
|
||||
m := &clientmock.ItemAPIMock{}
|
||||
m.On("List", context.Background(), "vault-id", mock.Anything).Return([]sdk.ItemOverview{}, nil)
|
||||
return m
|
||||
},
|
||||
check: func(t *testing.T, items []model.Item, err error) {
|
||||
require.NoError(t, err)
|
||||
require.Len(t, items, 0)
|
||||
},
|
||||
},
|
||||
"should return an error": {
|
||||
mockItemAPI: func() *clientmock.ItemAPIMock {
|
||||
m := &clientmock.ItemAPIMock{}
|
||||
@@ -191,8 +203,8 @@ func TestSDK_GetFileContent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check CreatedAt as soon as a new SDK version returns it
|
||||
func TestSDK_GetVaultsByTitle(t *testing.T) {
|
||||
now := time.Now()
|
||||
testCases := map[string]struct {
|
||||
mockVaultAPI func() *clientmock.VaultAPIMock
|
||||
check func(t *testing.T, vaults []model.Vault, err error)
|
||||
@@ -202,12 +214,14 @@ func TestSDK_GetVaultsByTitle(t *testing.T) {
|
||||
m := &clientmock.VaultAPIMock{}
|
||||
m.On("List", context.Background()).Return([]sdk.VaultOverview{
|
||||
{
|
||||
ID: "test-id",
|
||||
Title: VaultTitleEmployee,
|
||||
ID: "test-id",
|
||||
Title: VaultTitleEmployee,
|
||||
CreatedAt: now,
|
||||
},
|
||||
{
|
||||
ID: "test-id-2",
|
||||
Title: "Some other vault",
|
||||
ID: "test-id-2",
|
||||
Title: "Some other vault",
|
||||
CreatedAt: now,
|
||||
},
|
||||
}, nil)
|
||||
return m
|
||||
@@ -216,6 +230,7 @@ func TestSDK_GetVaultsByTitle(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Len(t, vaults, 1)
|
||||
require.Equal(t, "test-id", vaults[0].ID)
|
||||
require.Equal(t, now, vaults[0].CreatedAt)
|
||||
},
|
||||
},
|
||||
"should return a two vaults": {
|
||||
@@ -223,12 +238,14 @@ func TestSDK_GetVaultsByTitle(t *testing.T) {
|
||||
m := &clientmock.VaultAPIMock{}
|
||||
m.On("List", context.Background()).Return([]sdk.VaultOverview{
|
||||
{
|
||||
ID: "test-id",
|
||||
Title: VaultTitleEmployee,
|
||||
ID: "test-id",
|
||||
Title: VaultTitleEmployee,
|
||||
CreatedAt: now,
|
||||
},
|
||||
{
|
||||
ID: "test-id-2",
|
||||
Title: VaultTitleEmployee,
|
||||
ID: "test-id-2",
|
||||
Title: VaultTitleEmployee,
|
||||
CreatedAt: now,
|
||||
},
|
||||
}, nil)
|
||||
return m
|
||||
@@ -238,8 +255,10 @@ func TestSDK_GetVaultsByTitle(t *testing.T) {
|
||||
require.Len(t, vaults, 2)
|
||||
// Check the first vault
|
||||
require.Equal(t, "test-id", vaults[0].ID)
|
||||
require.Equal(t, now, vaults[0].CreatedAt)
|
||||
// Check the second vault
|
||||
require.Equal(t, "test-id-2", vaults[1].ID)
|
||||
require.Equal(t, now, vaults[1].CreatedAt)
|
||||
},
|
||||
},
|
||||
"should return an error": {
|
||||
|
@@ -12,7 +12,7 @@ type ConnectClientMock struct {
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) GetVaults() ([]onepassword.Vault, error) {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@@ -22,12 +22,12 @@ func (c *ConnectClientMock) GetVault(uuid string) (*onepassword.Vault, error) {
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) GetVaultByUUID(uuid string) (*onepassword.Vault, error) {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) GetVaultByTitle(title string) (*onepassword.Vault, error) {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ func (c *ConnectClientMock) GetVaultsByTitle(title string) ([]onepassword.Vault,
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) GetItems(vaultQuery string) ([]onepassword.Item, error) {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) GetItem(itemQuery, vaultQuery string) (*onepassword.Item, error) {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ func (c *ConnectClientMock) GetItemByUUID(uuid string, vaultQuery string) (*onep
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) GetItemByTitle(title string, vaultQuery string) (*onepassword.Item, error) {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@@ -62,37 +62,37 @@ func (c *ConnectClientMock) GetItemsByTitle(title string, vaultQuery string) ([]
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) CreateItem(item *onepassword.Item, vaultQuery string) (*onepassword.Item, error) {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) UpdateItem(item *onepassword.Item, vaultQuery string) (*onepassword.Item, error) {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) DeleteItem(item *onepassword.Item, vaultQuery string) error {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) DeleteItemByID(itemUUID string, vaultQuery string) error {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) DeleteItemByTitle(title string, vaultQuery string) error {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) GetFiles(itemQuery string, vaultQuery string) ([]onepassword.File, error) {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) GetFile(uuid string, itemQuery string, vaultQuery string) (*onepassword.File, error) {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@@ -105,26 +105,26 @@ func (c *ConnectClientMock) GetFileContent(file *onepassword.File) ([]byte, erro
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) DownloadFile(file *onepassword.File, targetDirectory string, overwrite bool) (string, error) {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) LoadStructFromItemByUUID(config interface{}, itemUUID string, vaultQuery string) error {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) LoadStructFromItemByTitle(config interface{}, itemTitle string, vaultQuery string) error {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) LoadStructFromItem(config interface{}, itemQuery string, vaultQuery string) error {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *ConnectClientMock) LoadStruct(config interface{}) error {
|
||||
//TODO implement me
|
||||
// Only implement this if mocking is needed
|
||||
panic("implement me")
|
||||
}
|
||||
|
Reference in New Issue
Block a user