diff --git a/cmd/main.go b/cmd/main.go index e92006e..3ee68f7 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -35,8 +35,6 @@ import ( "strings" "time" - "github.com/1Password/connect-sdk-go/connect" - // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) // to ensure that exec-entrypoint and run can make use of them. _ "k8s.io/client-go/plugin/pkg/client/auth" @@ -54,6 +52,7 @@ import ( onepasswordcomv1 "github.com/1Password/onepassword-operator/api/v1" "github.com/1Password/onepassword-operator/internal/controller" op "github.com/1Password/onepassword-operator/pkg/onepassword" + opclient "github.com/1Password/onepassword-operator/pkg/onepassword/client" "github.com/1Password/onepassword-operator/pkg/utils" "github.com/1Password/onepassword-operator/version" //+kubebuilder:scaffold:imports @@ -153,16 +152,16 @@ func main() { } // Setup One Password Client - opConnectClient, err := connect.NewClientFromEnvironment() + opClient, err := opclient.NewClient(version.OperatorVersion) if err != nil { - setupLog.Error(err, "unable to create Connect client") + setupLog.Error(err, "unable to create 1Password client") os.Exit(1) } if err = (&controller.OnePasswordItemReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - OpConnectClient: opConnectClient, + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + OpClient: opClient, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "OnePasswordItem") os.Exit(1) @@ -172,7 +171,7 @@ func main() { if err = (&controller.DeploymentReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), - OpConnectClient: opConnectClient, + OpClient: opClient, OpAnnotationRegExp: r, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "Deployment") @@ -202,7 +201,7 @@ func main() { } // Setup update secrets task - updatedSecretsPoller := op.NewManager(mgr.GetClient(), opConnectClient, shouldAutoRestartDeployments()) + updatedSecretsPoller := op.NewManager(mgr.GetClient(), opClient, shouldAutoRestartDeployments()) done := make(chan bool) ticker := time.NewTicker(getPollingIntervalForUpdatingSecrets()) go func() { diff --git a/internal/controller/deployment_controller.go b/internal/controller/deployment_controller.go index 67553e8..db3b2f4 100644 --- a/internal/controller/deployment_controller.go +++ b/internal/controller/deployment_controller.go @@ -31,11 +31,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" - "github.com/1Password/connect-sdk-go/connect" - kubeSecrets "github.com/1Password/onepassword-operator/pkg/kubernetessecrets" "github.com/1Password/onepassword-operator/pkg/logs" op "github.com/1Password/onepassword-operator/pkg/onepassword" + opclient "github.com/1Password/onepassword-operator/pkg/onepassword/client" "github.com/1Password/onepassword-operator/pkg/utils" appsv1 "k8s.io/api/apps/v1" @@ -55,7 +54,7 @@ var logDeployment = logf.Log.WithName("controller_deployment") type DeploymentReconciler struct { client.Client Scheme *runtime.Scheme - OpConnectClient connect.Client + OpClient opclient.Client OpAnnotationRegExp *regexp.Regexp } @@ -196,7 +195,7 @@ func (r *DeploymentReconciler) handleApplyingDeployment(deployment *appsv1.Deplo return nil } - item, err := op.GetOnePasswordItemByPath(r.OpConnectClient, annotations[op.ItemPathAnnotation]) + item, err := op.GetOnePasswordItemByPath(r.OpClient, annotations[op.ItemPathAnnotation]) if err != nil { return fmt.Errorf("Failed to retrieve item: %v", err) } diff --git a/internal/controller/onepassworditem_controller.go b/internal/controller/onepassworditem_controller.go index 57610b9..d38e55b 100644 --- a/internal/controller/onepassworditem_controller.go +++ b/internal/controller/onepassworditem_controller.go @@ -28,12 +28,11 @@ import ( "context" "fmt" - "github.com/1Password/connect-sdk-go/connect" - onepasswordv1 "github.com/1Password/onepassword-operator/api/v1" kubeSecrets "github.com/1Password/onepassword-operator/pkg/kubernetessecrets" "github.com/1Password/onepassword-operator/pkg/logs" op "github.com/1Password/onepassword-operator/pkg/onepassword" + opclient "github.com/1Password/onepassword-operator/pkg/onepassword/client" "github.com/1Password/onepassword-operator/pkg/utils" corev1 "k8s.io/api/core/v1" @@ -52,8 +51,8 @@ var finalizer = "onepassword.com/finalizer.secret" // OnePasswordItemReconciler reconciles a OnePasswordItem object type OnePasswordItemReconciler struct { client.Client - Scheme *runtime.Scheme - OpConnectClient connect.Client + Scheme *runtime.Scheme + OpClient opclient.Client } //+kubebuilder:rbac:groups=onepassword.com,resources=onepassworditems,verbs=get;list;watch;create;update;patch;delete @@ -164,7 +163,7 @@ func (r *OnePasswordItemReconciler) handleOnePasswordItem(resource *onepasswordv secretType := resource.Type autoRestart := resource.Annotations[op.RestartDeploymentsAnnotation] - item, err := op.GetOnePasswordItemByPath(r.OpConnectClient, resource.Spec.ItemPath) + item, err := op.GetOnePasswordItemByPath(r.OpClient, resource.Spec.ItemPath) if err != nil { return fmt.Errorf("Failed to retrieve item: %v", err) } diff --git a/pkg/kubernetessecrets/kubernetes_secrets_builder.go b/pkg/kubernetessecrets/kubernetes_secrets_builder.go index ccc3a81..d7982fd 100644 --- a/pkg/kubernetessecrets/kubernetes_secrets_builder.go +++ b/pkg/kubernetessecrets/kubernetes_secrets_builder.go @@ -3,6 +3,7 @@ package kubernetessecrets import ( "context" "fmt" + "github.com/1Password/onepassword-operator/pkg/onepassword/model" "regexp" "strings" @@ -11,8 +12,6 @@ import ( errs "errors" - "github.com/1Password/connect-sdk-go/onepassword" - "github.com/1Password/onepassword-operator/pkg/utils" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -34,11 +33,11 @@ var ErrCannotUpdateSecretType = errs.New("Cannot change secret type. Secret type var log = logf.Log -func CreateKubernetesSecretFromItem(kubeClient kubernetesClient.Client, secretName, namespace string, item *onepassword.Item, autoRestart string, labels map[string]string, secretType string, ownerRef *metav1.OwnerReference) error { +func CreateKubernetesSecretFromItem(kubeClient kubernetesClient.Client, secretName, namespace string, item *model.Item, autoRestart string, labels map[string]string, secretType string, ownerRef *metav1.OwnerReference) error { itemVersion := fmt.Sprint(item.Version) secretAnnotations := map[string]string{ VersionAnnotation: itemVersion, - ItemPathAnnotation: fmt.Sprintf("vaults/%v/items/%v", item.Vault.ID, item.ID), + ItemPathAnnotation: fmt.Sprintf("vaults/%v/items/%v", item.VaultID, item.ID), } if autoRestart != "" { @@ -92,7 +91,7 @@ func CreateKubernetesSecretFromItem(kubeClient kubernetesClient.Client, secretNa return nil } -func BuildKubernetesSecretFromOnePasswordItem(name, namespace string, annotations map[string]string, labels map[string]string, secretType string, item onepassword.Item, ownerRef *metav1.OwnerReference) *corev1.Secret { +func BuildKubernetesSecretFromOnePasswordItem(name, namespace string, annotations map[string]string, labels map[string]string, secretType string, item model.Item, ownerRef *metav1.OwnerReference) *corev1.Secret { var ownerRefs []metav1.OwnerReference if ownerRef != nil { ownerRefs = []metav1.OwnerReference{*ownerRef} @@ -111,7 +110,7 @@ func BuildKubernetesSecretFromOnePasswordItem(name, namespace string, annotation } } -func BuildKubernetesSecretData(fields []*onepassword.ItemField, files []*onepassword.File) map[string][]byte { +func BuildKubernetesSecretData(fields []model.ItemField, files []model.File) map[string][]byte { secretData := map[string][]byte{} for i := 0; i < len(fields); i++ { if fields[i].Value != "" { diff --git a/pkg/onepassword/client/client.go b/pkg/onepassword/client/client.go index f368f94..89be108 100644 --- a/pkg/onepassword/client/client.go +++ b/pkg/onepassword/client/client.go @@ -2,6 +2,7 @@ package client import ( "errors" + "os" "github.com/1Password/onepassword-operator/pkg/onepassword/client/connect" "github.com/1Password/onepassword-operator/pkg/onepassword/client/sdk" @@ -16,29 +17,24 @@ type Client interface { GetVaultsByTitle(title string) ([]model.Vault, error) } -// Config holds the configuration for creating a new 1Password client. -type Config struct { - ConnectHost string - ConnectToken string - UserAgent string - ServiceAccountToken string - IntegrationName string - IntegrationVersion string -} - // NewClient creates a new 1Password client based on the provided configuration. -func NewClient(config Config) (Client, error) { - if config.ServiceAccountToken != "" { +func NewClient(integrationVersion string) (Client, error) { + connectHost, _ := os.LookupEnv("OP_CONNECT_HOST") + connectToken, _ := os.LookupEnv("OP_CONNECT_TOKEN") + serviceAccountToken, _ := os.LookupEnv("OP_SERVICE_ACCOUNT_TOKEN") + + if serviceAccountToken != "" { return sdk.NewClient(sdk.Config{ - ServiceAccountToken: config.ServiceAccountToken, - IntegrationName: config.IntegrationName, - IntegrationVersion: config.IntegrationVersion, + ServiceAccountToken: serviceAccountToken, + IntegrationName: "1password-operator", + IntegrationVersion: integrationVersion, }) - } else if config.ConnectHost != "" && config.ConnectToken != "" { + } else if connectHost != "" && connectToken != "" { return connect.NewClient(connect.Config{ - ConnectHost: config.ConnectHost, - ConnectToken: config.ConnectToken, + ConnectHost: connectHost, + ConnectToken: connectToken, }), nil } - return nil, errors.New("invalid configuration. Either Connect or Service Account credentials should be set") + + return nil, errors.New("invalid configuration. Connect or Service Account credentials should be set") } diff --git a/pkg/onepassword/client/connect/connect.go b/pkg/onepassword/client/connect/connect.go index d1da4ef..92c5619 100644 --- a/pkg/onepassword/client/connect/connect.go +++ b/pkg/onepassword/client/connect/connect.go @@ -20,9 +20,10 @@ type Connect struct { client connect.Client } +// NewClient creates a new Connect client using provided configuration. func NewClient(config Config) *Connect { return &Connect{ - client: connect.NewClientWithUserAgent(config.ConnectHost, config.ConnectToken, config.UserAgent), + client: connect.NewClient(config.ConnectHost, config.ConnectToken), } } diff --git a/pkg/onepassword/items.go b/pkg/onepassword/items.go index f608013..1ed0934 100644 --- a/pkg/onepassword/items.go +++ b/pkg/onepassword/items.go @@ -4,36 +4,36 @@ import ( "fmt" "strings" - "github.com/1Password/connect-sdk-go/connect" - "github.com/1Password/connect-sdk-go/onepassword" - logf "sigs.k8s.io/controller-runtime/pkg/log" + + opclient "github.com/1Password/onepassword-operator/pkg/onepassword/client" + "github.com/1Password/onepassword-operator/pkg/onepassword/model" ) var logger = logf.Log.WithName("retrieve_item") -func GetOnePasswordItemByPath(opConnectClient connect.Client, path string) (*onepassword.Item, error) { - vaultValue, itemValue, err := ParseVaultAndItemFromPath(path) +func GetOnePasswordItemByPath(opClient opclient.Client, path string) (*model.Item, error) { + vaultIdentifier, itemIdentifier, err := ParseVaultAndItemFromPath(path) if err != nil { return nil, err } - vaultId, err := getVaultId(opConnectClient, vaultValue) + vaultID, err := getVaultID(opClient, vaultIdentifier) if err != nil { return nil, err } - itemId, err := getItemId(opConnectClient, itemValue, vaultId) + itemID, err := getItemID(opClient, vaultID, itemIdentifier) if err != nil { return nil, err } - item, err := opConnectClient.GetItem(itemId, vaultId) + item, err := opClient.GetItemByID(itemID, vaultID) if err != nil { return nil, err } for _, file := range item.Files { - _, err := opConnectClient.GetFileContent(file) + _, err := opClient.GetFileContent(vaultID, itemID, file.ID) if err != nil { return nil, err } @@ -50,7 +50,7 @@ func ParseVaultAndItemFromPath(path string) (string, string, error) { 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) { +func getVaultID(client opclient.Client, vaultIdentifier string) (string, error) { if !IsValidClientUUID(vaultIdentifier) { vaults, err := client.GetVaultsByTitle(vaultIdentifier) if err != nil { @@ -75,7 +75,7 @@ func getVaultId(client connect.Client, vaultIdentifier string) (string, error) { return vaultIdentifier, nil } -func getItemId(client connect.Client, itemIdentifier string, vaultId string) (string, error) { +func getItemID(client opclient.Client, vaultId, itemIdentifier string) (string, error) { if !IsValidClientUUID(itemIdentifier) { items, err := client.GetItemsByTitle(itemIdentifier, vaultId) if err != nil { diff --git a/pkg/onepassword/secret_update_handler.go b/pkg/onepassword/secret_update_handler.go index a24e7e1..d7f0156 100644 --- a/pkg/onepassword/secret_update_handler.go +++ b/pkg/onepassword/secret_update_handler.go @@ -8,10 +8,10 @@ import ( onepasswordv1 "github.com/1Password/onepassword-operator/api/v1" kubeSecrets "github.com/1Password/onepassword-operator/pkg/kubernetessecrets" "github.com/1Password/onepassword-operator/pkg/logs" + opclient "github.com/1Password/onepassword-operator/pkg/onepassword/client" + "github.com/1Password/onepassword-operator/pkg/onepassword/model" "github.com/1Password/onepassword-operator/pkg/utils" - "github.com/1Password/connect-sdk-go/connect" - "github.com/1Password/connect-sdk-go/onepassword" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -23,17 +23,17 @@ const lockTag = "operator.1password.io:ignore-secret" var log = logf.Log.WithName("update_op_kubernetes_secrets_task") -func NewManager(kubernetesClient client.Client, opConnectClient connect.Client, shouldAutoRestartDeploymentsGlobal bool) *SecretUpdateHandler { +func NewManager(kubernetesClient client.Client, opClient opclient.Client, shouldAutoRestartDeploymentsGlobal bool) *SecretUpdateHandler { return &SecretUpdateHandler{ client: kubernetesClient, - opConnectClient: opConnectClient, + opClient: opClient, shouldAutoRestartDeploymentsGlobal: shouldAutoRestartDeploymentsGlobal, } } type SecretUpdateHandler struct { client client.Client - opConnectClient connect.Client + opClient opclient.Client shouldAutoRestartDeploymentsGlobal bool } @@ -121,14 +121,14 @@ func (h *SecretUpdateHandler) updateKubernetesSecrets() (map[string]map[string]* OnePasswordItemPath := h.getPathFromOnePasswordItem(secret) - item, err := GetOnePasswordItemByPath(h.opConnectClient, OnePasswordItemPath) + item, err := GetOnePasswordItemByPath(h.opClient, OnePasswordItemPath) if err != nil { log.Error(err, "failed to retrieve 1Password item at path \"%s\" for secret \"%s\"", secret.Annotations[ItemPathAnnotation], secret.Name) continue } itemVersion := fmt.Sprint(item.Version) - itemPathString := fmt.Sprintf("vaults/%v/items/%v", item.Vault.ID, item.ID) + itemPathString := fmt.Sprintf("vaults/%v/items/%v", item.VaultID, item.ID) if currentVersion != itemVersion || secret.Annotations[ItemPathAnnotation] != itemPathString { if isItemLockedForForcedRestarts(item) { @@ -159,7 +159,7 @@ func (h *SecretUpdateHandler) updateKubernetesSecrets() (map[string]map[string]* return updatedSecrets, nil } -func isItemLockedForForcedRestarts(item *onepassword.Item) bool { +func isItemLockedForForcedRestarts(item *model.Item) bool { tags := item.Tags for i := 0; i < len(tags); i++ { if tags[i] == lockTag {