mirror of
https://github.com/external-secrets/external-secrets.git
synced 2024-12-14 11:57:59 +00:00
🧹Improve 1Password integration and docs (#1340)
This commit is contained in:
parent
fe0beaf169
commit
524e33bbeb
6 changed files with 36 additions and 28 deletions
|
@ -32,7 +32,7 @@ _**The 1Password API calls the entries in vaults 'Items'. These docs use the sam
|
|||
* External Secrets does not run this server. See [Deploy a Connect Server](#deploy-a-connect-server).
|
||||
* One Connect Server is needed per 1Password Automation Environment.
|
||||
* Many Vaults can be added to an Automation Environment, and Tokens can be generated in that Environment with access to any set or subset of those Vaults.
|
||||
* 1Password Connect Server version 1.3.0 or higher. 1.3.0 and 1.5.0 have been tested.
|
||||
* 1Password Connect Server version 1.5.6 or higher.
|
||||
|
||||
### Setup Authentication
|
||||
_Authentication requires a `1password-credentials.json` file provided to the Connect Server, and a related 'Access Token' for the client in this provider to authenticate to that Connect Server. Both of these are generated by 1Password._
|
||||
|
|
2
go.mod
2
go.mod
|
@ -94,7 +94,7 @@ require (
|
|||
software.sslmate.com/src/go-pkcs12 v0.0.0-20210415151418-c5206de65a78
|
||||
)
|
||||
|
||||
require github.com/1Password/connect-sdk-go v1.4.0
|
||||
require github.com/1Password/connect-sdk-go v1.5.0
|
||||
|
||||
require (
|
||||
github.com/argoproj/argo-cd/v2 v2.4.6
|
||||
|
|
12
go.sum
12
go.sum
|
@ -70,8 +70,8 @@ code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFj
|
|||
code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/1Password/connect-sdk-go v1.4.0 h1:c1cR22z69E634ZxEhjsBI08FNEcDBuM57IKMFDk04aM=
|
||||
github.com/1Password/connect-sdk-go v1.4.0/go.mod h1:ADZd9XFWwbBcnAayv7hVm9LTF0WkyoJ37jVA6BRtqzE=
|
||||
github.com/1Password/connect-sdk-go v1.5.0 h1:F0WJcLSzGg3iXEDY49/ULdszYKsQLGTzn+2cyYXqiyk=
|
||||
github.com/1Password/connect-sdk-go v1.5.0/go.mod h1:TdynFeyvaRoackENbJ8RfJokH+WAowAu1MLmUbdMq6s=
|
||||
github.com/Azure/azure-sdk-for-go v55.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v66.0.0+incompatible h1:bmmC38SlE8/E81nNADlgmVGurPWMHDX2YNXVQMrBpEE=
|
||||
github.com/Azure/azure-sdk-for-go v66.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
|
@ -114,10 +114,8 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
|
|||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/GoogleCloudPlatform/k8s-cloud-provider v1.16.1-0.20210702024009-ea6160c1d0e3/go.mod h1:8XasY4ymP2V/tn2OOV9ZadmiTE1FIB/h3W+yNlPttKw=
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.0.1 h1:GX8GAYDuhlFQnI2fRDHQhTlkHMz8bEn0jTI6LJU0mpw=
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.0.1 h1:GX8GAYDuhlFQnI2fRDHQhTlkHMz8bEn0jTI6LJU0mpw=
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.0.1/go.mod h1:BWJ+nMSHY3L41Zj7CA3uXnloDp7xxV0YvstAE7nKTaM=
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.0.1/go.mod h1:BWJ+nMSHY3L41Zj7CA3uXnloDp7xxV0YvstAE7nKTaM=
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM=
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
|
||||
github.com/IBM/go-sdk-core/v5 v5.9.5/go.mod h1:YlOwV9LeuclmT/qi/LAK2AsobbAP42veV0j68/rlZsE=
|
||||
github.com/IBM/go-sdk-core/v5 v5.10.1 h1:IEpjDJyB7okrC6bJ7fPZqBiOv+16VichT6kZXAz9bbQ=
|
||||
github.com/IBM/go-sdk-core/v5 v5.10.1/go.mod h1:u/33BzPy8sthgEhSeBnf6/kPCqwvC9VKw5byfqQfbe0=
|
||||
|
@ -1917,6 +1915,7 @@ gomodules.xyz/notify v0.1.0/go.mod h1:wGy0vLXGpabCg0j9WbjzXf7pM7Khz11FqCLtBbTujP
|
|||
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/gonum v0.6.2/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU=
|
||||
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
|
||||
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
|
||||
|
@ -2186,7 +2185,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|||
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20220512140231-539c8e751b99/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
|
|
|
@ -53,8 +53,11 @@ func (mockClient *OnePasswordMockClient) GetVaultByUUID(uuid string) (*onepasswo
|
|||
return &onepassword.Vault{}, nil
|
||||
}
|
||||
|
||||
// GetVaultByTitle unused fake.
|
||||
// GetVaultByTitle returns a vault, you must preload, only one.
|
||||
func (mockClient *OnePasswordMockClient) GetVaultByTitle(uuid string) (*onepassword.Vault, error) {
|
||||
if len(mockClient.MockVaults[uuid]) != 0 {
|
||||
return &mockClient.MockVaults[uuid][0], nil
|
||||
}
|
||||
return &onepassword.Vault{}, nil
|
||||
}
|
||||
|
||||
|
@ -82,9 +85,18 @@ func (mockClient *OnePasswordMockClient) GetItem(itemUUID, vaultUUID string) (*o
|
|||
return &onepassword.Item{}, errors.New("status 400: Invalid Item UUID")
|
||||
}
|
||||
|
||||
// GetItemByUUID unused fake.
|
||||
func (mockClient *OnePasswordMockClient) GetItemByUUID(uuid, vaultQuery string) (*onepassword.Item, error) {
|
||||
return &onepassword.Item{}, nil
|
||||
// GetItemByUUID returns a *onepassword.Item, you must preload.
|
||||
func (mockClient *OnePasswordMockClient) GetItemByUUID(itemUUID, vaultUUID string) (*onepassword.Item, error) {
|
||||
for _, item := range mockClient.MockItems[vaultUUID] {
|
||||
if item.ID == itemUUID {
|
||||
// load the fields that GetItemsByTitle does not
|
||||
item.Fields = mockClient.MockItemFields[vaultUUID][itemUUID]
|
||||
|
||||
return &item, nil
|
||||
}
|
||||
}
|
||||
|
||||
return &onepassword.Item{}, errors.New("status 400: Invalid Item UUID")
|
||||
}
|
||||
|
||||
// GetItemByTitle unused fake.
|
||||
|
@ -124,6 +136,11 @@ func (mockClient *OnePasswordMockClient) DeleteItemByID(itemUUID, vaultQuery str
|
|||
return nil
|
||||
}
|
||||
|
||||
// DeleteItemByTitle unused fake.
|
||||
func (mockClient *OnePasswordMockClient) DeleteItemByTitle(title, vaultQuery string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetFiles unused fake.
|
||||
func (mockClient *OnePasswordMockClient) GetFiles(itemQuery, vaultQuery string) ([]onepassword.File, error) {
|
||||
return []onepassword.File{}, nil
|
||||
|
|
|
@ -45,7 +45,6 @@ const (
|
|||
errFetchK8sSecret = "could not fetch ConnectToken Secret: %w"
|
||||
errMissingToken = "missing Secret Token"
|
||||
errGetVault = "error finding 1Password Vault: %w"
|
||||
errExpectedOneVault = "expected one 1Password Vault matching %w"
|
||||
errExpectedOneItem = "expected one 1Password Item matching %w"
|
||||
errGetItem = "error finding 1Password Item: %w"
|
||||
errKeyNotFound = "key not found in 1Password Vaults: %w"
|
||||
|
@ -173,7 +172,7 @@ func (provider *ProviderOnePassword) GetSecret(ctx context.Context, ref esv1beta
|
|||
// to be able to retrieve secrets from the provider.
|
||||
func (provider *ProviderOnePassword) Validate() (esv1beta1.ValidationResult, error) {
|
||||
for vaultName := range provider.vaults {
|
||||
_, err := provider.client.GetItems(vaultName)
|
||||
_, err := provider.client.GetVaultByTitle(vaultName)
|
||||
if err != nil {
|
||||
return esv1beta1.ValidationResultError, err
|
||||
}
|
||||
|
@ -211,15 +210,12 @@ func (provider *ProviderOnePassword) GetAllSecrets(ctx context.Context, ref esv1
|
|||
secretData := make(map[string][]byte)
|
||||
sortedVaults := sortVaults(provider.vaults)
|
||||
for _, vaultName := range sortedVaults {
|
||||
vaults, err := provider.client.GetVaultsByTitle(vaultName)
|
||||
vault, err := provider.client.GetVaultByTitle(vaultName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errGetVault, err)
|
||||
}
|
||||
if len(vaults) != 1 {
|
||||
return nil, fmt.Errorf(errExpectedOneVault, fmt.Errorf(incorrectCountFormat, vaultName, len(vaults)))
|
||||
}
|
||||
|
||||
err = provider.getAllForVault(vaults[0].ID, ref, secretData)
|
||||
err = provider.getAllForVault(vault.ID, ref, secretData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -236,22 +232,19 @@ func (provider *ProviderOnePassword) Close(ctx context.Context) error {
|
|||
func (provider *ProviderOnePassword) findItem(name string) (*onepassword.Item, error) {
|
||||
sortedVaults := sortVaults(provider.vaults)
|
||||
for _, vaultName := range sortedVaults {
|
||||
vaults, err := provider.client.GetVaultsByTitle(vaultName)
|
||||
vault, err := provider.client.GetVaultByTitle(vaultName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errGetVault, err)
|
||||
}
|
||||
if len(vaults) != 1 {
|
||||
return nil, fmt.Errorf(errExpectedOneVault, fmt.Errorf(incorrectCountFormat, vaultName, len(vaults)))
|
||||
}
|
||||
|
||||
// use GetItemsByTitle instead of GetItemByTitle in order to handle length cases
|
||||
items, err := provider.client.GetItemsByTitle(name, vaults[0].ID)
|
||||
items, err := provider.client.GetItemsByTitle(name, vault.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errGetItem, err)
|
||||
}
|
||||
switch {
|
||||
case len(items) == 1:
|
||||
return provider.client.GetItem(items[0].ID, items[0].Vault.ID)
|
||||
return provider.client.GetItemByUUID(items[0].ID, items[0].Vault.ID)
|
||||
case len(items) > 1:
|
||||
return nil, fmt.Errorf(errExpectedOneItem, fmt.Errorf(incorrectCountFormat, name, len(items)))
|
||||
}
|
||||
|
@ -301,7 +294,7 @@ func (provider *ProviderOnePassword) getFields(item *onepassword.Item, property
|
|||
}
|
||||
|
||||
func (provider *ProviderOnePassword) getAllFields(item onepassword.Item, ref esv1beta1.ExternalSecretFind, secretData map[string][]byte) error {
|
||||
i, err := provider.client.GetItem(item.ID, item.Vault.ID)
|
||||
i, err := provider.client.GetItemByUUID(item.ID, item.Vault.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf(errGetItem, err)
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ func TestFindItem(t *testing.T) {
|
|||
{
|
||||
checkNote: "two vaults",
|
||||
findItemName: myItem,
|
||||
expectedErr: fmt.Errorf(errExpectedOneVault, fmt.Errorf("'my-vault', got 2")),
|
||||
expectedErr: fmt.Errorf("key not found in 1Password Vaults: my-item in: map[my-shared-vault:2 my-vault:1]"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue