kube-1password-secrets/internal/onepassword/client.go
Marcus Noble bb4f2232db
Updated to op v2
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2024-09-28 09:40:41 +01:00

83 lines
1.9 KiB
Go

package onepassword
import (
"encoding/json"
"fmt"
"os/exec"
)
// Client is the 1Password client
type Client struct{}
// Secret contains the credentials from a 1Password secret
type Secret struct {
ID string `json:"id"`
Title string `json:"title"`
Username string `json:"username"`
Password string `json:"password"`
SecretText string `json:"secretText"`
}
// New authenticates with the provided values and returns a new 1Password client
func New() (*Client, error) {
client := &Client{}
if err := client.authenticate(); err != nil {
return nil, err
}
return client, nil
}
func (op *Client) authenticate() error {
cmd := exec.Command("op", "user", "get", "--me")
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("Cannot verify auth: %s\n%s", err, output)
}
return nil
}
func (op Client) runCmd(args ...string) ([]byte, error) {
args = append(args, "--format=json")
cmd := exec.Command("op", args...)
res, err := cmd.CombinedOutput()
if err != nil {
err = fmt.Errorf("error calling 1Password: %s\n%s", err, res)
}
return res, err
}
// GetSecret returns the values from the secret stored in 1Password with a UUID matching the secretID
func (op *Client) GetSecret(vault, secretID string) (*Secret, error) {
res, err := op.runCmd("item", "get", secretID, "--reveal", fmt.Sprintf("--vault=%s", vault))
if err != nil {
return nil, err
}
item := response{}
if err := json.Unmarshal(res, &item); err != nil {
return nil, err
}
secret := &Secret{
ID: item.UUID,
Title: item.Title,
Username: "",
Password: "",
SecretText: "",
}
if len(item.Fields) > 0 {
for _, field := range item.Fields {
switch field.Name {
case "username":
secret.Username = field.Value
case "password":
secret.Password = field.Value
case "notesPlain":
secret.SecretText = field.Value
}
}
}
return secret, nil
}