mirror of
https://github.com/1Password/onepassword-operator.git
synced 2025-10-22 07:28:06 +00:00
Merge pull request #1 from 1Password/get_by_title
Allow vault and item titles in item path
This commit is contained in:
13
README.md
13
README.md
@@ -77,9 +77,7 @@ kind: OnePasswordItem # {insert_new_name}
|
|||||||
metadata:
|
metadata:
|
||||||
name: {item_name} #this name will also be used for naming the generated kubernetes secret
|
name: {item_name} #this name will also be used for naming the generated kubernetes secret
|
||||||
spec:
|
spec:
|
||||||
item-path: "vaults/{vaultId}/items/{itemId}"
|
item-path: "vaults/{vault_id_or_title}/items/{item_id_or_title}"
|
||||||
# where vaultId is the id of the vault in which to find the item
|
|
||||||
# where itemId is the id of the item that you want to store as a Kubernetes Secret
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Deploy the OnePasswordItem to Kubernetes:
|
Deploy the OnePasswordItem to Kubernetes:
|
||||||
@@ -104,7 +102,7 @@ kind: Deployment
|
|||||||
metadata:
|
metadata:
|
||||||
name: deployment-example
|
name: deployment-example
|
||||||
annotations:
|
annotations:
|
||||||
onepasswordoperator/item-path: "vaults/{vaultId}/items/{itemId}"
|
onepasswordoperator/item-path: "vaults/{vault_id_or_title}/items/{item_id_or_title}"
|
||||||
onepasswordoperator/item-name: "{secret_name}"
|
onepasswordoperator/item-name: "{secret_name}"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -114,6 +112,13 @@ Note: Deleting the Deployment that you've created will automatically delete the
|
|||||||
|
|
||||||
If a 1Password Item that is linked to a Kubernetes Secret is updated within the `POLLING_INTERVAL` the associated Kubernetes Secret will be updated. Furthermore, any deployments using that secret will be given a rolling restart.
|
If a 1Password Item that is linked to a Kubernetes Secret is updated within the `POLLING_INTERVAL` the associated Kubernetes Secret will be updated. Furthermore, any deployments using that secret will be given a rolling restart.
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
**NOTE**
|
||||||
|
|
||||||
|
If multiple 1Password vaults/items have the same `title` when using a title in the access path, the desired action will be performed on the oldest vault/item. Furthermore, titles that include white space characters cannot be used.
|
||||||
|
|
||||||
|
---
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
### Running Tests
|
### Running Tests
|
||||||
|
@@ -28,7 +28,7 @@ spec:
|
|||||||
- name: OPERATOR_NAME
|
- name: OPERATOR_NAME
|
||||||
value: "onepassword-connect-operator"
|
value: "onepassword-connect-operator"
|
||||||
- name: OP_CONNECT_HOST
|
- name: OP_CONNECT_HOST
|
||||||
value: "http://secret-service:8080"
|
value: "http://onepassword-connect:8080"
|
||||||
- name: POLLING_INTERVAL
|
- name: POLLING_INTERVAL
|
||||||
value: "10"
|
value: "10"
|
||||||
- name: OP_CONNECT_TOKEN
|
- name: OP_CONNECT_TOKEN
|
||||||
|
2
go.mod
2
go.mod
@@ -3,7 +3,7 @@ module github.com/1Password/onepassword-operator
|
|||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/1Password/connect-sdk-go v0.0.1
|
github.com/1Password/connect-sdk-go v0.0.2
|
||||||
github.com/go-logr/logr v0.1.0 // indirect
|
github.com/go-logr/logr v0.1.0 // indirect
|
||||||
github.com/operator-framework/operator-sdk v0.19.0
|
github.com/operator-framework/operator-sdk v0.19.0
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
2
go.sum
2
go.sum
@@ -21,6 +21,8 @@ contrib.go.opencensus.io/exporter/ocagent v0.6.0/go.mod h1:zmKjrJcdo0aYcVS7bmEeS
|
|||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
github.com/1Password/connect-sdk-go v0.0.1 h1:qsFZQDQ+JirZRwSom/p6zzNqkkcYAYx4EXivUyPhvBo=
|
github.com/1Password/connect-sdk-go v0.0.1 h1:qsFZQDQ+JirZRwSom/p6zzNqkkcYAYx4EXivUyPhvBo=
|
||||||
github.com/1Password/connect-sdk-go v0.0.1/go.mod h1:br2BWk2sqgJFnOFK5WSDfBBmwQ6E7hV9LoPqrtHGRNY=
|
github.com/1Password/connect-sdk-go v0.0.1/go.mod h1:br2BWk2sqgJFnOFK5WSDfBBmwQ6E7hV9LoPqrtHGRNY=
|
||||||
|
github.com/1Password/connect-sdk-go v0.0.2 h1:IBamxGS17zItC9TRwp/0G0Fh1GRV3mqOkcWvpK05Mx8=
|
||||||
|
github.com/1Password/connect-sdk-go v0.0.2/go.mod h1:br2BWk2sqgJFnOFK5WSDfBBmwQ6E7hV9LoPqrtHGRNY=
|
||||||
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
|
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
|
||||||
github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc=
|
github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc=
|
||||||
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||||
|
@@ -6,8 +6,10 @@ import (
|
|||||||
|
|
||||||
type TestClient struct {
|
type TestClient struct {
|
||||||
GetVaultsFunc func() ([]onepassword.Vault, error)
|
GetVaultsFunc func() ([]onepassword.Vault, error)
|
||||||
|
GetVaultsByTitleFunc func(title string) ([]onepassword.Vault, error)
|
||||||
GetItemFunc func(uuid string, vaultUUID string) (*onepassword.Item, error)
|
GetItemFunc func(uuid string, vaultUUID string) (*onepassword.Item, error)
|
||||||
GetItemsFunc func(vaultUUID string) ([]onepassword.Item, error)
|
GetItemsFunc func(vaultUUID string) ([]onepassword.Item, error)
|
||||||
|
GetItemsByTitleFunc func(title string, vaultUUID string) ([]onepassword.Item, error)
|
||||||
GetItemByTitleFunc func(title string, vaultUUID string) (*onepassword.Item, error)
|
GetItemByTitleFunc func(title string, vaultUUID string) (*onepassword.Item, error)
|
||||||
CreateItemFunc func(item *onepassword.Item, vaultUUID string) (*onepassword.Item, error)
|
CreateItemFunc func(item *onepassword.Item, vaultUUID string) (*onepassword.Item, error)
|
||||||
UpdateItemFunc func(item *onepassword.Item, vaultUUID string) (*onepassword.Item, error)
|
UpdateItemFunc func(item *onepassword.Item, vaultUUID string) (*onepassword.Item, error)
|
||||||
@@ -16,7 +18,9 @@ type TestClient struct {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
GetGetVaultsFunc func() ([]onepassword.Vault, error)
|
GetGetVaultsFunc func() ([]onepassword.Vault, error)
|
||||||
|
DoGetVaultsByTitleFunc func(title string) ([]onepassword.Vault, error)
|
||||||
GetGetItemFunc func(uuid string, vaultUUID string) (*onepassword.Item, error)
|
GetGetItemFunc func(uuid string, vaultUUID string) (*onepassword.Item, error)
|
||||||
|
DoGetItemsByTitleFunc func(title string, vaultUUID string) ([]onepassword.Item, error)
|
||||||
DoGetItemByTitleFunc func(title string, vaultUUID string) (*onepassword.Item, error)
|
DoGetItemByTitleFunc func(title string, vaultUUID string) (*onepassword.Item, error)
|
||||||
DoCreateItemFunc func(item *onepassword.Item, vaultUUID string) (*onepassword.Item, error)
|
DoCreateItemFunc func(item *onepassword.Item, vaultUUID string) (*onepassword.Item, error)
|
||||||
DoDeleteItemFunc func(item *onepassword.Item, vaultUUID string) error
|
DoDeleteItemFunc func(item *onepassword.Item, vaultUUID string) error
|
||||||
@@ -29,6 +33,10 @@ func (m *TestClient) GetVaults() ([]onepassword.Vault, error) {
|
|||||||
return GetGetVaultsFunc()
|
return GetGetVaultsFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *TestClient) GetVaultsByTitle(title string) ([]onepassword.Vault, error) {
|
||||||
|
return DoGetVaultsByTitleFunc(title)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *TestClient) GetItem(uuid string, vaultUUID string) (*onepassword.Item, error) {
|
func (m *TestClient) GetItem(uuid string, vaultUUID string) (*onepassword.Item, error) {
|
||||||
return GetGetItemFunc(uuid, vaultUUID)
|
return GetGetItemFunc(uuid, vaultUUID)
|
||||||
}
|
}
|
||||||
@@ -37,6 +45,10 @@ func (m *TestClient) GetItems(vaultUUID string) ([]onepassword.Item, error) {
|
|||||||
return DoGetItemsFunc(vaultUUID)
|
return DoGetItemsFunc(vaultUUID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *TestClient) GetItemsByTitle(title, vaultUUID string) ([]onepassword.Item, error) {
|
||||||
|
return DoGetItemsByTitleFunc(title, vaultUUID)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *TestClient) GetItemByTitle(title string, vaultUUID string) (*onepassword.Item, error) {
|
func (m *TestClient) GetItemByTitle(title string, vaultUUID string) (*onepassword.Item, error) {
|
||||||
return DoGetItemByTitleFunc(title, vaultUUID)
|
return DoGetItemByTitleFunc(title, vaultUUID)
|
||||||
}
|
}
|
||||||
|
@@ -6,13 +6,26 @@ import (
|
|||||||
|
|
||||||
"github.com/1Password/connect-sdk-go/connect"
|
"github.com/1Password/connect-sdk-go/connect"
|
||||||
"github.com/1Password/connect-sdk-go/onepassword"
|
"github.com/1Password/connect-sdk-go/onepassword"
|
||||||
|
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var logger = logf.Log.WithName("retrieve_item")
|
||||||
|
|
||||||
func GetOnePasswordItemByPath(opConnectClient connect.Client, path string) (*onepassword.Item, error) {
|
func GetOnePasswordItemByPath(opConnectClient connect.Client, path string) (*onepassword.Item, error) {
|
||||||
vaultId, itemId, err := ParseVaultIdAndItemIdFromPath(path)
|
vaultValue, itemValue, err := ParseVaultAndItemFromPath(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
vaultId, err := getVaultId(opConnectClient, vaultValue)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
itemId, err := getItemId(opConnectClient, itemValue, vaultId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
item, err := opConnectClient.GetItem(itemId, vaultId)
|
item, err := opConnectClient.GetItem(itemId, vaultId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -20,10 +33,60 @@ func GetOnePasswordItemByPath(opConnectClient connect.Client, path string) (*one
|
|||||||
return item, nil
|
return item, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseVaultIdAndItemIdFromPath(path string) (string, string, error) {
|
func ParseVaultAndItemFromPath(path string) (string, string, error) {
|
||||||
splitPath := strings.Split(path, "/")
|
splitPath := strings.Split(path, "/")
|
||||||
if len(splitPath) == 4 && splitPath[0] == "vaults" && splitPath[2] == "items" {
|
if len(splitPath) == 4 && splitPath[0] == "vaults" && splitPath[2] == "items" {
|
||||||
return splitPath[1], splitPath[3], nil
|
return splitPath[1], splitPath[3], nil
|
||||||
}
|
}
|
||||||
return "", "", fmt.Errorf("%q is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`", path)
|
return "", "", fmt.Errorf("%q is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getVaultId(client connect.Client, vaultIdentifier string) (string, error) {
|
||||||
|
if !IsValidClientUUID(vaultIdentifier) {
|
||||||
|
vaults, err := client.GetVaultsByTitle(vaultIdentifier)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(vaults) == 0 {
|
||||||
|
return "", fmt.Errorf("No vaults found with identifier %q", vaultIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
oldestVault := vaults[0]
|
||||||
|
if len(vaults) > 1 {
|
||||||
|
for _, returnedVault := range vaults {
|
||||||
|
if returnedVault.CreatedAt.Before(oldestVault.CreatedAt) {
|
||||||
|
oldestVault = returnedVault
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.Info(fmt.Sprintf("%v 1Password vaults found with the title %q. Will use vault %q as it is the oldest.", len(vaults), vaultIdentifier, oldestVault.ID))
|
||||||
|
}
|
||||||
|
vaultIdentifier = oldestVault.ID
|
||||||
|
}
|
||||||
|
return vaultIdentifier, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getItemId(client connect.Client, itemIdentifier string, vaultId string) (string, error) {
|
||||||
|
if !IsValidClientUUID(itemIdentifier) {
|
||||||
|
items, err := client.GetItemsByTitle(itemIdentifier, vaultId)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(items) == 0 {
|
||||||
|
return "", fmt.Errorf("No items found with identifier %q", itemIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
oldestItem := items[0]
|
||||||
|
if len(items) > 1 {
|
||||||
|
for _, returnedItem := range items {
|
||||||
|
if returnedItem.CreatedAt.Before(oldestItem.CreatedAt) {
|
||||||
|
oldestItem = returnedItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.Info(fmt.Sprintf("%v 1Password items found with the title %q. Will use item %q as it is the oldest.", len(items), itemIdentifier, oldestItem.ID))
|
||||||
|
}
|
||||||
|
itemIdentifier = oldestItem.ID
|
||||||
|
}
|
||||||
|
return itemIdentifier, nil
|
||||||
|
}
|
||||||
|
20
pkg/onepassword/uuid.go
Normal file
20
pkg/onepassword/uuid.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package onepassword
|
||||||
|
|
||||||
|
// UUIDLength defines the required length of UUIDs
|
||||||
|
const UUIDLength = 26
|
||||||
|
|
||||||
|
// IsValidClientUUID returns true if the given client uuid is valid.
|
||||||
|
func IsValidClientUUID(uuid string) bool {
|
||||||
|
if len(uuid) != UUIDLength {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range uuid {
|
||||||
|
valid := (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')
|
||||||
|
if !valid {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
56
vendor/github.com/1Password/connect-sdk-go/connect/client.go
generated
vendored
56
vendor/github.com/1Password/connect-sdk-go/connect/client.go
generated
vendored
@@ -24,8 +24,10 @@ const (
|
|||||||
// Client Represents an available 1Password Connect API to connect to
|
// Client Represents an available 1Password Connect API to connect to
|
||||||
type Client interface {
|
type Client interface {
|
||||||
GetVaults() ([]onepassword.Vault, error)
|
GetVaults() ([]onepassword.Vault, error)
|
||||||
|
GetVaultsByTitle(uuid string) ([]onepassword.Vault, error)
|
||||||
GetItem(uuid string, vaultUUID string) (*onepassword.Item, error)
|
GetItem(uuid string, vaultUUID string) (*onepassword.Item, error)
|
||||||
GetItems(vaultUUID string) ([]onepassword.Item, error)
|
GetItems(vaultUUID string) ([]onepassword.Item, error)
|
||||||
|
GetItemsByTitle(title string, vaultUUID string) ([]onepassword.Item, error)
|
||||||
GetItemByTitle(title string, vaultUUID string) (*onepassword.Item, error)
|
GetItemByTitle(title string, vaultUUID string) (*onepassword.Item, error)
|
||||||
CreateItem(item *onepassword.Item, vaultUUID string) (*onepassword.Item, error)
|
CreateItem(item *onepassword.Item, vaultUUID string) (*onepassword.Item, error)
|
||||||
UpdateItem(item *onepassword.Item, vaultUUID string) (*onepassword.Item, error)
|
UpdateItem(item *onepassword.Item, vaultUUID string) (*onepassword.Item, error)
|
||||||
@@ -127,6 +129,39 @@ func (rs *restClient) GetVaults() ([]onepassword.Vault, error) {
|
|||||||
return vaults, nil
|
return vaults, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rs *restClient) GetVaultsByTitle(title string) ([]onepassword.Vault, error) {
|
||||||
|
span := rs.tracer.StartSpan("GetVaultsByTitle")
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
filter := url.QueryEscape(fmt.Sprintf("title eq \"%s\"", title))
|
||||||
|
itemURL := fmt.Sprintf("/v1/vaults?filter=%s", filter)
|
||||||
|
request, err := rs.buildRequest(http.MethodGet, itemURL, http.NoBody, span)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := rs.client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("Unable to retrieve vaults. Receieved %q for %q", response.Status, itemURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
vaults := []onepassword.Vault{}
|
||||||
|
if err := json.Unmarshal(body, &vaults); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return vaults, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetItem Get a specific Item from the 1Password Connect API
|
// GetItem Get a specific Item from the 1Password Connect API
|
||||||
func (rs *restClient) GetItem(uuid string, vaultUUID string) (*onepassword.Item, error) {
|
func (rs *restClient) GetItem(uuid string, vaultUUID string) (*onepassword.Item, error) {
|
||||||
span := rs.tracer.StartSpan("GetItem")
|
span := rs.tracer.StartSpan("GetItem")
|
||||||
@@ -163,6 +198,21 @@ func (rs *restClient) GetItem(uuid string, vaultUUID string) (*onepassword.Item,
|
|||||||
func (rs *restClient) GetItemByTitle(title string, vaultUUID string) (*onepassword.Item, error) {
|
func (rs *restClient) GetItemByTitle(title string, vaultUUID string) (*onepassword.Item, error) {
|
||||||
span := rs.tracer.StartSpan("GetItemByTitle")
|
span := rs.tracer.StartSpan("GetItemByTitle")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
items, err := rs.GetItemsByTitle(title, vaultUUID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(items) != 1 {
|
||||||
|
return nil, fmt.Errorf("Found %d item(s) in vault %q with title %q", len(items), vaultUUID, title)
|
||||||
|
}
|
||||||
|
|
||||||
|
return rs.GetItem(items[0].ID, items[0].Vault.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rs *restClient) GetItemsByTitle(title string, vaultUUID string) ([]onepassword.Item, error) {
|
||||||
|
span := rs.tracer.StartSpan("GetItemsByTitle")
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
filter := url.QueryEscape(fmt.Sprintf("title eq \"%s\"", title))
|
filter := url.QueryEscape(fmt.Sprintf("title eq \"%s\"", title))
|
||||||
itemURL := fmt.Sprintf("/v1/vaults/%s/items?filter=%s", vaultUUID, filter)
|
itemURL := fmt.Sprintf("/v1/vaults/%s/items?filter=%s", vaultUUID, filter)
|
||||||
@@ -190,11 +240,7 @@ func (rs *restClient) GetItemByTitle(title string, vaultUUID string) (*onepasswo
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(items) != 1 {
|
return items, nil
|
||||||
return nil, fmt.Errorf("Found %d item(s) in vault %q with title %q", len(items), vaultUUID, title)
|
|
||||||
}
|
|
||||||
|
|
||||||
return rs.GetItem(items[0].ID, items[0].Vault.ID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *restClient) GetItems(vaultUUID string) ([]onepassword.Item, error) {
|
func (rs *restClient) GetItems(vaultUUID string) ([]onepassword.Item, error) {
|
||||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -1,6 +1,6 @@
|
|||||||
# cloud.google.com/go v0.49.0
|
# cloud.google.com/go v0.49.0
|
||||||
cloud.google.com/go/compute/metadata
|
cloud.google.com/go/compute/metadata
|
||||||
# github.com/1Password/connect-sdk-go v0.0.1
|
# github.com/1Password/connect-sdk-go v0.0.2
|
||||||
github.com/1Password/connect-sdk-go/connect
|
github.com/1Password/connect-sdk-go/connect
|
||||||
github.com/1Password/connect-sdk-go/onepassword
|
github.com/1Password/connect-sdk-go/onepassword
|
||||||
# github.com/Azure/go-autorest/autorest v0.9.3-0.20191028180845-3492b2aff503
|
# github.com/Azure/go-autorest/autorest v0.9.3-0.20191028180845-3492b2aff503
|
||||||
|
Reference in New Issue
Block a user