{"id":35672338,"url":"https://github.com/bborbe/teamvault-utils","last_synced_at":"2026-01-05T19:03:41.535Z","repository":{"id":57554013,"uuid":"96414431","full_name":"bborbe/teamvault-utils","owner":"bborbe","description":"Commandline tools for Teamvault","archived":false,"fork":false,"pushed_at":"2025-10-19T10:41:10.000Z","size":13243,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-19T11:43:57.048Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bborbe.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-07-06T09:43:04.000Z","updated_at":"2025-10-19T10:41:12.000Z","dependencies_parsed_at":"2023-01-20T03:46:37.065Z","dependency_job_id":"db54f06d-180f-4b6d-971d-ebe062bad996","html_url":"https://github.com/bborbe/teamvault-utils","commit_stats":null,"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"purl":"pkg:github/bborbe/teamvault-utils","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bborbe%2Fteamvault-utils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bborbe%2Fteamvault-utils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bborbe%2Fteamvault-utils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bborbe%2Fteamvault-utils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bborbe","download_url":"https://codeload.github.com/bborbe/teamvault-utils/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bborbe%2Fteamvault-utils/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28218051,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2026-01-05T02:00:06.358Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-05T19:01:59.820Z","updated_at":"2026-01-05T19:03:41.529Z","avatar_url":"https://github.com/bborbe.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Teamvault Utils\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/bborbe/teamvault-utils/v4.svg)](https://pkg.go.dev/github.com/bborbe/teamvault-utils/v4)\n[![CI](https://github.com/bborbe/teamvault-utils/actions/workflows/ci.yml/badge.svg)](https://github.com/bborbe/teamvault-utils/actions/workflows/ci.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/bborbe/teamvault-utils/v4)](https://goreportcard.com/report/github.com/bborbe/teamvault-utils/v4)\n\nA Go library and CLI tools for interacting with TeamVault secret management system. Provides type-safe access to passwords, usernames, URLs, and files stored in TeamVault, with support for template parsing and configuration generation.\n\n## Features\n\n- **Type-Safe API**: Strongly typed interfaces for accessing TeamVault secrets\n- **Multiple Connectors**: Remote, cache, disk fallback, and dummy connectors\n- **Template Parsing**: Parse configuration templates with TeamVault placeholders\n- **Config Generation**: Generate configuration files from templates\n- **CLI Tools**: Command-line utilities for quick secret access\n- **Dependency Injection**: Clean architecture with testable components\n\n---\n\n* [Installation](#installation)\n* [Quick Start](#quick-start)\n* [Library Usage](#library-usage)\n* [API Documentation](#api-documentation)\n* [CLI Tools](#cli-tools)\n* [Development](#development)\n* [Testing](#testing)\n* [License](#license)\n\n---\n\n## Installation\n\n```bash\ngo get github.com/bborbe/teamvault-utils/v4\n```\n\n## Quick Start\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"net/http\"\n\n    teamvault \"github.com/bborbe/teamvault-utils/v4\"\n    libtime \"github.com/bborbe/time\"\n)\n\nfunc main() {\n    ctx := context.Background()\n\n    // Create a connector\n    connector := teamvault.NewRemoteConnector(\n        http.DefaultClient,\n        teamvault.Url(\"https://teamvault.example.com\"),\n        teamvault.User(\"my-user\"),\n        teamvault.Password(\"my-pass\"),\n        libtime.NewCurrentDateTime(),\n    )\n\n    // Retrieve a password\n    password, err := connector.Password(ctx, teamvault.Key(\"vLVLbm\"))\n    if err != nil {\n        panic(err)\n    }\n\n    fmt.Printf(\"Password: %s\\n\", password)\n}\n```\n\n## Library Usage\n\n### Using the Connector Interface\n\nThe `Connector` interface provides access to TeamVault secrets:\n\n```go\nimport (\n    \"context\"\n    \"net/http\"\n\n    teamvault \"github.com/bborbe/teamvault-utils/v4\"\n    libtime \"github.com/bborbe/time\"\n)\n\nfunc example() {\n    ctx := context.Background()\n\n    connector := teamvault.NewRemoteConnector(\n        http.DefaultClient,\n        teamvault.Url(\"https://teamvault.example.com\"),\n        teamvault.User(\"my-user\"),\n        teamvault.Password(\"my-pass\"),\n        libtime.NewCurrentDateTime(),\n    )\n\n    // Get password\n    password, err := connector.Password(ctx, teamvault.Key(\"abc123\"))\n    if err != nil {\n        // handle error\n    }\n\n    // Get username\n    user, err := connector.User(ctx, teamvault.Key(\"abc123\"))\n    if err != nil {\n        // handle error\n    }\n\n    // Get URL\n    url, err := connector.Url(ctx, teamvault.Key(\"abc123\"))\n    if err != nil {\n        // handle error\n    }\n\n    // Get file\n    file, err := connector.File(ctx, teamvault.Key(\"abc123\"))\n    if err != nil {\n        // handle error\n    }\n\n    // Search for secrets\n    keys, err := connector.Search(ctx, \"database\")\n    if err != nil {\n        // handle error\n    }\n}\n```\n\n### Template Parsing with ConfigParser\n\nParse configuration templates containing TeamVault placeholders:\n\n```go\nimport (\n    \"context\"\n\n    teamvault \"github.com/bborbe/teamvault-utils/v4\"\n)\n\nfunc parseConfig(connector teamvault.Connector) {\n    ctx := context.Background()\n\n    parser := teamvault.NewConfigParser(connector)\n\n    template := []byte(`\ndatabase:\n  username: {{ \"vLVLbm\" | teamvaultUser }}\n  password: {{ \"vLVLbm\" | teamvaultPassword }}\n  url: {{ \"vLVLbm\" | teamvaultUrl }}\n`)\n\n    result, err := parser.Parse(ctx, template)\n    if err != nil {\n        // handle error\n    }\n\n    // result now contains resolved values\n}\n```\n\n### Using Different Connector Types\n\n**Cache Connector** (for performance):\n\n```go\nconnector := teamvault.NewCacheConnector(\n    teamvault.NewRemoteConnector(\n        http.DefaultClient,\n        teamvault.Url(\"https://teamvault.example.com\"),\n        teamvault.User(\"my-user\"),\n        teamvault.Password(\"my-pass\"),\n        libtime.NewCurrentDateTime(),\n    ),\n)\n```\n\n**Disk Fallback Connector** (for reliability):\n\n```go\nconnector := teamvault.NewDiskFallbackConnector(\n    teamvault.NewRemoteConnector(\n        http.DefaultClient,\n        teamvault.Url(\"https://teamvault.example.com\"),\n        teamvault.User(\"my-user\"),\n        teamvault.Password(\"my-pass\"),\n        libtime.NewCurrentDateTime(),\n    ),\n)\n```\n\n**Dummy Connector** (for testing):\n\n```go\nconnector := teamvault.NewDummyConnector()\n```\n\n### Creating Connectors with Factory\n\nUse the factory package for simplified connector creation:\n\n```go\nimport (\n    \"context\"\n    \"net/http\"\n\n    teamvault \"github.com/bborbe/teamvault-utils/v4\"\n    \"github.com/bborbe/teamvault-utils/v4/factory\"\n    libtime \"github.com/bborbe/time\"\n)\n\nfunc createConnector() (teamvault.Connector, error) {\n    ctx := context.Background()\n\n    httpClient, err := factory.CreateHttpClient(ctx)\n    if err != nil {\n        return nil, err\n    }\n\n    connector, err := factory.CreateConnectorWithConfig(\n        ctx,\n        httpClient,\n        teamvault.TeamvaultConfigPath(\"~/.teamvault.json\"),\n        teamvault.Url(\"\"),\n        teamvault.User(\"\"),\n        teamvault.Password(\"\"),\n        teamvault.Staging(false),\n        true, // enable cache\n        libtime.NewCurrentDateTime(),\n    )\n    if err != nil {\n        return nil, err\n    }\n\n    return connector, nil\n}\n```\n\n## API Documentation\n\nFor complete API documentation, visit [pkg.go.dev](https://pkg.go.dev/github.com/bborbe/teamvault-utils/v4).\n\n---\n\n## CLI Tools\n\nThe library includes several command-line tools for quick secret access.\n\n### Teamvault Get Password\n\nInstall:\n\n```bash\ngo get github.com/bborbe/teamvault-utils/v4/cmd/teamvault-password\n```\n\nRun:\n\n```bash\nteamvault-password \\\n  --teamvault-config ~/.teamvault.json \\\n  --teamvault-key vLVLbm\n```\n\n### Teamvault Get Username\n\nInstall:\n\n```bash\ngo get github.com/bborbe/teamvault-utils/v4/cmd/teamvault-username\n```\n\nRun:\n\n```bash\nteamvault-username \\\n  --teamvault-config ~/.teamvault.json \\\n  --teamvault-key vLVLbm\n```\n\n### Teamvault Get URL\n\nInstall:\n\n```bash\ngo get github.com/bborbe/teamvault-utils/v4/cmd/teamvault-url\n```\n\nRun:\n\n```bash\nteamvault-url \\\n  --teamvault-config ~/.teamvault.json \\\n  --teamvault-key vLVLbm\n```\n\n### Parse Config with Teamvault Secrets\n\nInstall:\n\n```bash\ngo get github.com/bborbe/teamvault-utils/v4/cmd/teamvault-config-parser\n```\n\nSample config template:\n\n```bash\nfoo=bar\nusername={{ \"vLVLbm\" | teamvaultUser }}\npassword={{ \"vLVLbm\" | teamvaultPassword }}\nurl={{ \"vLVLbm\" | teamvaultUrl }}\n```\n\nRun:\n\n```bash\ncat my.config | teamvault-config-parser \\\n  --teamvault-config ~/.teamvault.json \\\n  --logtostderr \\\n  -v=2\n```\n\n### Generate Config Directory from Templates\n\nInstall:\n\n```bash\ngo get github.com/bborbe/teamvault-utils/v4/cmd/teamvault-config-dir-generator\n```\n\nTeamVault config file (~/.teamvault.json):\n\n```json\n{\n    \"url\": \"https://teamvault.example.com\",\n    \"user\": \"my-user\",\n    \"pass\": \"my-pass\"\n}\n```\n\nRun:\n\n```bash\nteamvault-config-dir-generator \\\n  --teamvault-config ~/.teamvault.json \\\n  --source-dir templates \\\n  --target-dir results \\\n  --logtostderr \\\n  -v=2\n```\n\n---\n\n## Development\n\n### Running Tests\n\n```bash\nmake test\n```\n\n### Code Generation (Mocks)\n\n```bash\nmake generate\n```\n\n### Full Development Workflow\n\n```bash\nmake precommit  # Format, test, lint, and check\n```\n\n---\n\n## Full Example\n\nHere's a complete, runnable example demonstrating real-world usage patterns combining multiple features:\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"net/http\"\n    \"os\"\n\n    teamvault \"github.com/bborbe/teamvault-utils/v4\"\n    libtime \"github.com/bborbe/time\"\n)\n\nfunc main() {\n    ctx := context.Background()\n\n    // Create a cached connector for better performance\n    // The cache connector wraps the remote connector and caches responses\n    connector := teamvault.NewCacheConnector(\n        teamvault.NewRemoteConnector(\n            http.DefaultClient,\n            teamvault.Url(\"https://teamvault.example.com\"),\n            teamvault.User(\"my-user\"),\n            teamvault.Password(\"my-pass\"),\n            libtime.NewCurrentDateTime(),\n        ),\n    )\n\n    // Example 1: Retrieve individual secrets\n    password, err := connector.Password(ctx, teamvault.Key(\"vLVLbm\"))\n    if err != nil {\n        fmt.Fprintf(os.Stderr, \"Error getting password: %v\\n\", err)\n        os.Exit(1)\n    }\n    fmt.Printf(\"Retrieved password (length: %d)\\n\", len(password.String()))\n\n    user, err := connector.User(ctx, teamvault.Key(\"vLVLbm\"))\n    if err != nil {\n        fmt.Fprintf(os.Stderr, \"Error getting user: %v\\n\", err)\n        os.Exit(1)\n    }\n    fmt.Printf(\"Retrieved user: %s\\n\", user.String())\n\n    // Example 2: Parse a configuration template\n    parser := teamvault.NewConfigParser(connector)\n\n    configTemplate := []byte(`\n# Database Configuration\ndatabase:\n  host: {{ \"vLVLbm\" | teamvaultUrl }}\n  username: {{ \"vLVLbm\" | teamvaultUser }}\n  password: {{ \"vLVLbm\" | teamvaultPassword }}\n\n# Application Settings\napp:\n  environment: {{ \"production\" | env }}\n  debug: false\n`)\n\n    result, err := parser.Parse(ctx, configTemplate)\n    if err != nil {\n        fmt.Fprintf(os.Stderr, \"Error parsing config: %v\\n\", err)\n        os.Exit(1)\n    }\n\n    fmt.Println(\"\\nGenerated Configuration:\")\n    fmt.Println(string(result))\n\n    // Example 3: Generate configuration files from templates\n    generator := teamvault.NewConfigGenerator(parser)\n\n    err = generator.Generate(\n        ctx,\n        teamvault.SourceDirectory(\"./templates\"),\n        teamvault.TargetDirectory(\"./config\"),\n    )\n    if err != nil {\n        fmt.Fprintf(os.Stderr, \"Error generating configs: %v\\n\", err)\n        os.Exit(1)\n    }\n\n    fmt.Println(\"\\nConfiguration files generated successfully!\")\n}\n```\n\nThis example demonstrates:\n- Creating a cached connector for performance optimization\n- Retrieving individual secrets (password, user)\n- Parsing configuration templates with TeamVault placeholders\n- Generating multiple configuration files from a template directory\n\n---\n\n## Testing\n\nTesting code that uses this library is straightforward using the mock connector or dummy connector:\n\n```go\nimport (\n    \"context\"\n    \"testing\"\n\n    teamvault \"github.com/bborbe/teamvault-utils/v4\"\n    \"github.com/bborbe/teamvault-utils/v4/mocks\"\n)\n\nfunc TestYourCode(t *testing.T) {\n    ctx := context.Background()\n\n    // Use mock connector for testing\n    mockConnector := \u0026mocks.Connector{}\n    mockConnector.PasswordReturns(teamvault.Password(\"test-password\"), nil)\n\n    // Test your code with the mock\n    result, err := mockConnector.Password(ctx, teamvault.Key(\"test-key\"))\n    if err != nil {\n        t.Fatal(err)\n    }\n\n    if result != \"test-password\" {\n        t.Errorf(\"expected test-password, got %s\", result)\n    }\n}\n\nfunc TestWithDummyConnector(t *testing.T) {\n    // Or use dummy connector for simple tests\n    connector := teamvault.NewDummyConnector()\n\n    // Test your code with dummy connector\n}\n```\n\n---\n\n## License\n\nThis project is licensed under the BSD-style license. See the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbborbe%2Fteamvault-utils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbborbe%2Fteamvault-utils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbborbe%2Fteamvault-utils/lists"}