fix: add involves edge from task to agent:nomos at creation
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled

Plus sync vendor directory for Docker build compatibility.
This commit is contained in:
2026-08-11 22:03:12 +02:00
parent 7d6a3320d4
commit febc153b7f
3384 changed files with 945212 additions and 2 deletions

23
vendor/github.com/infisical/go-sdk/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,23 @@
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
go.work.sum
.DS_Store

11
vendor/github.com/infisical/go-sdk/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,11 @@
MIT License
Copyright (c) 2025 Infisical
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
NOTE: This license pertains specifically to components of the codebase that do not possess an explicit license. Each distinct SDK incorporated within this software is governed by its individual licensing terms and conditions. The provisions outlined in this MIT license are applicable to those segments of the codebase not explicitly covered by their respective licenses.

40
vendor/github.com/infisical/go-sdk/README.md generated vendored Normal file
View File

@@ -0,0 +1,40 @@
<h1 align="center">
<img width="300" src="/img/logoname-white.svg#gh-dark-mode-only" alt="infisical">
</h1>
<p align="center">
<p align="center"><b>Infisical Go SDK</b></p>
<h4 align="center">
|
<a href="https://infisical.com/docs/sdks/languages/go">Documentation</a> |
<a href="https://www.infisical.com">Website</a> |
<a href="https://infisical.com/slack">Slack</a> |
</h4>
<h4 align="center">
<a href="https://github.com/Infisical/go-sdk/blob/main/LICENSE">
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="Infisical SDKs are released under the MIT license." />
</a>
<a href="https://infisical.com/slack">
<img src="https://img.shields.io/badge/chat-on%20Slack-blueviolet" alt="Slack community channel" />
</a>
<a href="https://twitter.com/infisical">
<img src="https://img.shields.io/twitter/follow/infisical?label=Follow" alt="Infisical Twitter" />
</a>
</h4>
## Introduction
**[Infisical](https://infisical.com)** is the open source secret management platform that teams use to centralize their secrets like API keys, database credentials, and configurations.
If youre working with Go, the official Infisical Go SDK package is the easiest way to fetch and work with secrets for your application. You can read the documentation [here](https://infisical.com/docs/sdks/languages/go).
## Documentation
You can find the documentation for the Go SDK on our [SDK documentation page](https://infisical.com/docs/sdks/languages/go).
## Security
Please do not file GitHub issues or post on our public forum for security vulnerabilities, as they are public!
Infisical takes security issues very seriously. If you have any concerns about Infisical or believe you have uncovered a vulnerability, please get in touch via the e-mail address security@infisical.com. In the message, try to provide a description of the issue and ideally a way of reproducing it. The security team will get back to you as soon as possible.
Note that this security address should be used only for undisclosed vulnerabilities. Please report any security problems to us before disclosing it publicly.

537
vendor/github.com/infisical/go-sdk/auth.go generated vendored Normal file
View File

@@ -0,0 +1,537 @@
package infisical
import (
"context"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"net/http"
"os"
"strings"
"time"
api "github.com/infisical/go-sdk/packages/api/auth"
"github.com/infisical/go-sdk/packages/models"
"github.com/infisical/go-sdk/packages/util"
"github.com/oracle/oci-go-sdk/v65/common"
v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
)
type KubernetesAuthLoginOptions struct {
IdentityID string
ServiceAccountTokenPath string
}
type AuthInterface interface {
SetAccessToken(accessToken string)
GetAccessToken() string
GetOrganizationSlug() string
// When set, this will scope the login session to the specified sub-organization the machine identity has access to. If left empty, the session defaults to the organization where the machine identity was created in.
WithOrganizationSlug(organizationSlug string) AuthInterface
// When set, the next AzureAuthLogin call will request a token for the specified User-Assigned Managed Identity (UAMI) by its client ID. Leave unset for System-Assigned Managed Identity.
WithAzureClientID(clientID string) AuthInterface
UniversalAuthLogin(clientID string, clientSecret string) (credential MachineIdentityCredential, err error)
JwtAuthLogin(identityID string, jwt string) (credential MachineIdentityCredential, err error)
KubernetesAuthLogin(identityID string, serviceAccountTokenPath string) (credential MachineIdentityCredential, err error)
KubernetesRawServiceAccountTokenLogin(identityID string, serviceAccountToken string) (credential MachineIdentityCredential, err error)
AzureAuthLogin(identityID string, resource string) (credential MachineIdentityCredential, err error)
GcpIdTokenAuthLogin(identityID string) (credential MachineIdentityCredential, err error)
GcpIamAuthLogin(identityID string, serviceAccountKeyFilePath string) (credential MachineIdentityCredential, err error)
AwsIamAuthLogin(identityId string) (credential MachineIdentityCredential, err error)
OidcAuthLogin(identityId string, jwt string) (credential MachineIdentityCredential, err error)
OciAuthLogin(options OciAuthLoginOptions) (credential MachineIdentityCredential, err error)
LdapAuthLogin(identityID string, username string, password string) (credential MachineIdentityCredential, err error)
RevokeAccessToken() error
}
type Auth struct {
client *InfisicalClient
organizationSlug string
azureClientID string
}
func (a *Auth) SetAccessToken(accessToken string) {
a.client.setPlainAccessToken(accessToken)
}
func (a *Auth) GetOrganizationSlug() string {
return a.organizationSlug
}
func (a *Auth) WithOrganizationSlug(organizationSlug string) AuthInterface {
a.organizationSlug = organizationSlug
return a
}
func (a *Auth) WithAzureClientID(clientID string) AuthInterface {
a.azureClientID = clientID
return a
}
func (a *Auth) GetAccessToken() string {
// case: user has set an access token manually, so we get it directly from the credential
if a.client.authMethod == util.ACCESS_TOKEN {
if parsedCreds, ok := a.client.credential.(models.AccessTokenCredential); ok {
return parsedCreds.AccessToken
}
return ""
}
return a.client.tokenDetails.AccessToken
}
func (a *Auth) RevokeAccessToken() error {
if a.client.tokenDetails.AccessToken == "" {
return errors.New("sdk client is not authenticated, cannot revoke access token")
}
_, err := api.CallRevokeAccessToken(a.client.httpClient, api.RevokeAccessTokenRequest{
AccessToken: a.client.tokenDetails.AccessToken,
})
if err != nil {
return err
}
a.client.clearAccessToken()
return nil
}
func (a *Auth) UniversalAuthLogin(clientID string, clientSecret string) (credential MachineIdentityCredential, err error) {
if clientID == "" {
clientID = os.Getenv(util.INFISICAL_UNIVERSAL_AUTH_CLIENT_ID_ENV_NAME)
}
if clientSecret == "" {
clientSecret = os.Getenv(util.INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
credential, err = api.CallUniversalAuthLogin(a.client.httpClient, api.UniversalAuthLoginRequest{
ClientID: clientID,
ClientSecret: clientSecret,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.UniversalAuthCredential{ClientID: clientID, ClientSecret: clientSecret},
util.UNIVERSAL_AUTH,
)
return credential, nil
}
func (a *Auth) KubernetesAuthLogin(identityID string, serviceAccountTokenPath string) (credential MachineIdentityCredential, err error) {
if serviceAccountTokenPath == "" {
serviceAccountTokenPath = os.Getenv(util.DEFAULT_KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH)
}
if identityID == "" {
identityID = os.Getenv(util.INFISICAL_KUBERNETES_IDENTITY_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
serviceAccountToken, serviceAccountTokenErr := util.GetKubernetesServiceAccountToken(serviceAccountTokenPath)
if serviceAccountTokenErr != nil {
return MachineIdentityCredential{}, serviceAccountTokenErr
}
credential, err = api.CallKubernetesAuthLogin(a.client.httpClient, api.KubernetesAuthLoginRequest{
IdentityID: identityID,
JWT: serviceAccountToken,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.KubernetesCredential{IdentityID: identityID, ServiceAccountToken: serviceAccountToken},
util.KUBERNETES,
)
return credential, nil
}
func (a *Auth) KubernetesRawServiceAccountTokenLogin(identityID string, serviceAccountToken string) (credential MachineIdentityCredential, err error) {
if identityID == "" {
identityID = os.Getenv(util.INFISICAL_KUBERNETES_IDENTITY_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
credential, err = api.CallKubernetesAuthLogin(a.client.httpClient, api.KubernetesAuthLoginRequest{
IdentityID: identityID,
JWT: serviceAccountToken,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.KubernetesCredential{IdentityID: identityID, ServiceAccountToken: serviceAccountToken},
util.KUBERNETES,
)
return credential, nil
}
func (a *Auth) AzureAuthLogin(identityID string, resource string) (credential MachineIdentityCredential, err error) {
if identityID == "" {
identityID = os.Getenv(util.INFISICAL_AZURE_AUTH_IDENTITY_ID_ENV_NAME)
}
clientID := a.azureClientID
if clientID == "" {
clientID = os.Getenv(util.INFISICAL_AZURE_AUTH_CLIENT_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
jwt, jwtError := util.GetAzureMetadataToken(a.client.httpClient, resource, clientID)
if jwtError != nil {
return MachineIdentityCredential{}, jwtError
}
credential, err = api.CallAzureAuthLogin(a.client.httpClient, api.AzureAuthLoginRequest{
IdentityID: identityID,
JWT: jwt,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.AzureCredential{IdentityID: identityID, Resource: resource, ClientID: clientID},
util.AZURE,
)
return credential, nil
}
func (a *Auth) GcpIdTokenAuthLogin(identityID string) (credential MachineIdentityCredential, err error) {
if identityID == "" {
identityID = os.Getenv(util.INFISICAL_GCP_AUTH_IDENTITY_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
jwt, jwtError := util.GetGCPMetadataToken(a.client.httpClient, identityID)
if jwtError != nil {
return MachineIdentityCredential{}, jwtError
}
credential, err = api.CallGCPAuthLogin(a.client.httpClient, api.GCPAuthLoginRequest{
IdentityID: identityID,
JWT: jwt,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.GCPIDTokenCredential{IdentityID: identityID},
util.GCP_ID_TOKEN,
)
return credential, nil
}
func (a *Auth) GcpIamAuthLogin(identityID string, serviceAccountKeyFilePath string) (credential MachineIdentityCredential, err error) {
if identityID == "" {
identityID = os.Getenv(util.INFISICAL_GCP_AUTH_IDENTITY_ID_ENV_NAME)
}
if serviceAccountKeyFilePath == "" {
serviceAccountKeyFilePath = os.Getenv(util.INFISICAL_GCP_IAM_SERVICE_ACCOUNT_KEY_FILE_PATH_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
jwt, jwtError := util.GetGCPIamServiceAccountToken(identityID, serviceAccountKeyFilePath)
if jwtError != nil {
return MachineIdentityCredential{}, jwtError
}
credential, err = api.CallGCPAuthLogin(a.client.httpClient, api.GCPAuthLoginRequest{
IdentityID: identityID,
JWT: jwt,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.GCPIAMCredential{IdentityID: identityID, ServiceAccountKeyFilePath: serviceAccountKeyFilePath},
util.GCP_IAM,
)
return credential, nil
}
func (a *Auth) AwsIamAuthLogin(identityId string) (credential MachineIdentityCredential, err error) {
if identityId == "" {
identityId = os.Getenv(util.INFISICAL_AWS_IAM_AUTH_IDENTITY_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
awsCredentials, awsRegion, err := util.RetrieveAwsCredentials()
if err != nil {
return MachineIdentityCredential{}, err
}
// Prepare request for signing
iamRequestURL := fmt.Sprintf("https://sts.%s.amazonaws.com/", awsRegion)
iamRequestBody := "Action=GetCallerIdentity&Version=2011-06-15"
req, err := http.NewRequest(http.MethodPost, iamRequestURL, strings.NewReader(iamRequestBody))
if err != nil {
return MachineIdentityCredential{}, fmt.Errorf("error creating HTTP request: %v", err)
}
currentTime := time.Now().UTC()
req.Header.Add("X-Amz-Date", currentTime.Format("20060102T150405Z"))
hashGenerator := sha256.New()
hashGenerator.Write([]byte(iamRequestBody))
payloadHash := fmt.Sprintf("%x", hashGenerator.Sum(nil))
signer := v4.NewSigner()
err = signer.SignHTTP(context.TODO(), awsCredentials, req, payloadHash, "sts", awsRegion, time.Now())
if err != nil {
return MachineIdentityCredential{}, fmt.Errorf("error signing request: %v", err)
}
realHeaders := make(map[string]string)
for name, values := range req.Header {
if strings.ToLower(name) == "content-length" {
continue
}
realHeaders[name] = values[0]
}
realHeaders["Host"] = fmt.Sprintf("sts.%s.amazonaws.com", awsRegion)
realHeaders["Content-Type"] = "application/x-www-form-urlencoded; charset=utf-8"
realHeaders["Content-Length"] = fmt.Sprintf("%d", len(iamRequestBody))
// convert the headers to a json marshalled string
jsonStringHeaders, err := json.Marshal(realHeaders)
if err != nil {
return MachineIdentityCredential{}, fmt.Errorf("error marshalling headers: %v", err)
}
credential, tokenErr := api.CallAWSIamAuthLogin(a.client.httpClient, api.AwsIamAuthLoginRequest{
HTTPRequestMethod: req.Method,
// Encoding is intended, we decode it on severside, and I know everything happening on the server is being done correctly. So it's something broken in this code somewhere.
IamRequestBody: base64.StdEncoding.EncodeToString([]byte(iamRequestBody)),
IamRequestHeaders: base64.StdEncoding.EncodeToString(jsonStringHeaders),
IdentityId: identityId,
OrganizationSlug: organizationSlug,
})
if tokenErr != nil {
return MachineIdentityCredential{}, tokenErr
}
a.client.setAccessToken(
credential,
models.AWSIAMCredential{IdentityID: identityId},
util.AWS_IAM,
)
return credential, nil
}
func (a *Auth) OidcAuthLogin(identityId string, jwt string) (credential MachineIdentityCredential, err error) {
if identityId == "" {
identityId = os.Getenv(util.INFISICAL_OIDC_AUTH_IDENTITY_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
credential, err = api.CallOidcAuthLogin(a.client.httpClient, api.OidcAuthLoginRequest{
IdentityID: identityId,
JWT: jwt,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.OIDCCredential{IdentityID: identityId},
util.OIDC_AUTH,
)
return credential, nil
}
func (a *Auth) JwtAuthLogin(identityID string, jwt string) (credential MachineIdentityCredential, err error) {
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
credential, err = api.CallJwtAuthLogin(a.client.httpClient, api.JwtAuthLoginRequest{
IdentityID: identityID,
JWT: jwt,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.JWTCredential{IdentityID: identityID, JWT: jwt},
util.JWT_AUTH,
)
return credential, nil
}
func (a *Auth) OciAuthLogin(options OciAuthLoginOptions) (credential MachineIdentityCredential, err error) {
if options.IdentityID == "" {
options.IdentityID = os.Getenv(util.INFISICAL_OCI_AUTH_IDENTITY_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
provider := common.NewRawConfigurationProvider(
options.TenancyID,
options.UserID,
options.Region,
options.Fingerprint,
options.PrivateKey,
options.Passphrase,
)
requestURL := fmt.Sprintf("https://identity.%s.oraclecloud.com/20160918/users/%s", options.Region, options.UserID)
req, err := http.NewRequest("GET", requestURL, nil)
if err != nil {
return MachineIdentityCredential{}, fmt.Errorf("OciAuthLogin: failed to create request: %w", err)
}
req.Header.Set("host", fmt.Sprintf("identity.%s.oraclecloud.com", options.Region))
req.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat))
signer := common.DefaultRequestSigner(provider)
err = signer.Sign(req)
if err != nil {
return MachineIdentityCredential{}, fmt.Errorf("OciAuthLogin: failed to sign request: %w", err)
}
headersMap := make(map[string]string)
for name, values := range req.Header {
if len(values) > 0 {
// Convert header names to lowercase to match OCI signature expectations
lowerName := strings.ToLower(name)
headersMap[lowerName] = values[0]
}
}
credential, err = api.CallOciAuthLogin(a.client.httpClient, api.OciAuthLoginRequest{
IdentityID: options.IdentityID,
UserOcid: options.UserID,
Headers: headersMap,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.OCICredential{
IdentityID: options.IdentityID,
PrivateKey: options.PrivateKey,
Fingerprint: options.Fingerprint,
UserID: options.UserID,
TenancyID: options.TenancyID,
Region: options.Region,
Passphrase: options.Passphrase,
},
util.OCI_AUTH,
)
return credential, nil
}
func (a *Auth) LdapAuthLogin(identityID string, username string, password string) (credential MachineIdentityCredential, err error) {
if identityID == "" {
identityID = os.Getenv(util.INFISICAL_LDAP_AUTH_IDENTITY_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
credential, err = api.CallLdapAuthLogin(a.client.httpClient, api.LdapAuthLoginRequest{
IdentityID: identityID,
Username: username,
Password: password,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.LDAPCredential{IdentityID: identityID, Username: username, Password: password},
util.LDAP_AUTH,
)
return credential, nil
}
func NewAuth(client *InfisicalClient) AuthInterface {
return &Auth{client: client}
}

515
vendor/github.com/infisical/go-sdk/client.go generated vendored Normal file
View File

@@ -0,0 +1,515 @@
package infisical
import (
"context"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"io"
"os"
"math"
"math/rand"
"net"
"reflect"
"strconv"
"strings"
"sync"
"time"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/go-resty/resty/v2"
"github.com/hashicorp/golang-lru/v2/expirable"
"github.com/infisical/go-sdk/packages/models"
"github.com/infisical/go-sdk/packages/util"
)
type LogLevel string
const (
LogLevelDebug LogLevel = "debug"
)
type InfisicalClient struct {
authMethod util.AuthMethod
credential interface{}
tokenDetails MachineIdentityCredential
lastFetchedTime time.Time
firstFetchedTime time.Time
mu sync.RWMutex
// refreshMu is used to prevent concurrent token refreshes.
// Only one refresh should happen at a time to avoid race conditions.
refreshMu sync.Mutex
cache *expirable.LRU[string, interface{}]
httpClient *resty.Client
config Config
secrets SecretsInterface
folders FoldersInterface
auth AuthInterface
dynamicSecrets DynamicSecretsInterface
kms KmsInterface
ssh SshInterface
logger zerolog.Logger
}
type InfisicalClientInterface interface {
UpdateConfiguration(config Config)
Secrets() SecretsInterface
Folders() FoldersInterface
Auth() AuthInterface
DynamicSecrets() DynamicSecretsInterface
Kms() KmsInterface
Ssh() SshInterface
}
type ExponentialBackoffStrategy struct {
// Base delay between retries. Defaults to 1 second
BaseDelay time.Duration
// Maximum number of retries. Defaults to 3
MaxRetries int
// Maximum delay between retries. Defaults to 30 seconds
MaxDelay time.Duration
}
func (s *ExponentialBackoffStrategy) GetDelay(retryCount int) time.Duration {
if s.BaseDelay == 0 {
s.BaseDelay = 1 * time.Second
}
if s.MaxDelay == 0 {
s.MaxDelay = 30 * time.Second
}
if s.MaxRetries == 0 {
s.MaxRetries = 3
}
delay := s.BaseDelay * time.Duration(math.Pow(2, float64(retryCount)))
// if delay is greater than the user-configured max delay, set the delay to the max delay
if delay > s.MaxDelay {
delay = s.MaxDelay
}
return s.Jitter(delay)
}
func (s *ExponentialBackoffStrategy) Jitter(delay time.Duration) time.Duration {
// 20% jitter, negative and positive
jitterFactor := 0.2
// generates random value in [-0.2, +0.2] range
randomFactor := (rand.Float64()*2 - 1) * jitterFactor
jitter := time.Duration(randomFactor * float64(delay))
return delay + jitter
}
type RetryRequestsConfig struct {
ExponentialBackoff *ExponentialBackoffStrategy
}
type Config struct {
SiteUrl string `default:"https://app.infisical.com"`
CaCertificate string
LogLevel LogLevel // Specify the log level for the SDK. If set to debug, the SDK will print to stdout with verbose logging. Defaults to no logging.
UserAgent string `default:"infisical-go-sdk"` // User-Agent header to be used on requests sent by the SDK. Defaults to `infisical-go-sdk`. Do not modify this unless you have a reason to do so.
AutoTokenRefresh *bool // Whether or not to automatically refresh the auth token after using one of the .Auth() methods. Defaults to `true` when nil. Pass a pointer to `false` to disable.
SilentMode bool // If enabled, the SDK will not print any warnings to the console.
CacheExpiryInSeconds int // Defines how long certain API responses should be cached in memory, in seconds. When set to a positive value, responses from specific fetch API requests (like secret fetching) will be cached for this duration. Set to 0 to disable caching. Defaults to 0.
CustomHeaders map[string]string
RetryRequestsConfig *RetryRequestsConfig
LogWriter io.Writer
}
func setupLogger(logLevel LogLevel, logWriter io.Writer) zerolog.Logger {
// very annoying but zerolog doesn't allow us to change one color without changing all of them
// these are the default colors for each level, except for warn
levelColors := map[string]string{
"trace": "\033[35m", // magenta
"debug": "\033[33m", // yellow
"info": "\033[32m", // green
"warn": "\033[33m", // yellow (this one is custom, the default is red \033[31m)
"error": "\033[31m", // red
"fatal": "\033[31m", // red
"panic": "\033[31m", // red
}
// map full level names to abbreviated forms (default zerolog behavior)
// see consoleDefaultFormatLevel, in zerolog for example
levelAbbrev := map[string]string{
"trace": "TRC",
"debug": "DBG",
"info": "INF",
"warn": "WRN",
"error": "ERR",
"fatal": "FTL",
"panic": "PNC",
}
// default to stderr
if logWriter == nil {
logWriter = os.Stderr
}
logger := log.Output(zerolog.ConsoleWriter{
Out: logWriter,
TimeFormat: time.RFC3339,
FormatLevel: func(i interface{}) string {
level := fmt.Sprintf("%s", i)
color := levelColors[level]
if color == "" {
color = "\033[0m" // no color for unknown levels
}
abbrev := levelAbbrev[level]
if abbrev == "" {
abbrev = strings.ToUpper(level) // fallback to uppercase if unknown
}
return color + abbrev + "\033[0m"
},
})
if logLevel != "" {
level, err := zerolog.ParseLevel(string(logLevel))
if err != nil {
logger.Warn().Msgf("Invalid log level: %s", logLevel)
} else {
logger = logger.Level(level)
logger.Debug().Msgf("Infisical SDK log level set to %s", logLevel)
}
} else {
logger = logger.Level(zerolog.InfoLevel)
}
return logger
}
// autoTokenRefreshEnabled returns true if AutoTokenRefresh is unset (nil) or
// explicitly set to true. nil is treated as the default-on case so that
// callers who omit the field keep the historical behavior, while callers that
// pass a pointer to false can actually disable the background refresh.
func autoTokenRefreshEnabled(cfg Config) bool {
return cfg.AutoTokenRefresh == nil || *cfg.AutoTokenRefresh
}
func setDefaults(cfg *Config) {
t := reflect.TypeOf(*cfg) // we need to dereference the pointer to get the struct type
v := reflect.ValueOf(cfg).Elem()
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
defaultVal := field.Tag.Get("default")
if defaultVal == "" {
continue
}
switch field.Type.Kind() {
case reflect.Int:
if v.Field(i).Int() == 0 {
val, _ := strconv.Atoi(defaultVal)
v.Field(i).SetInt(int64(val))
}
case reflect.String:
if v.Field(i).String() == "" {
v.Field(i).SetString(defaultVal)
}
}
}
}
// BoolPtr returns a pointer to the given bool value. Use this helper when
// setting AutoTokenRefresh in Config, e.g.: AutoTokenRefresh: infisical.BoolPtr(false).
func BoolPtr(v bool) *bool { return &v }
func (c *InfisicalClient) setAccessToken(tokenDetails MachineIdentityCredential, credential interface{}, authMethod util.AuthMethod) {
c.mu.Lock()
defer c.mu.Unlock()
c.tokenDetails = tokenDetails
c.lastFetchedTime = time.Now()
if c.authMethod != authMethod || c.firstFetchedTime.IsZero() {
c.firstFetchedTime = time.Now()
c.authMethod = authMethod
}
c.credential = credential
c.httpClient.SetAuthScheme("Bearer")
c.httpClient.SetAuthToken(c.tokenDetails.AccessToken)
}
func (c *InfisicalClient) clearAccessToken() {
c.mu.Lock()
defer c.mu.Unlock()
c.tokenDetails = MachineIdentityCredential{}
c.authMethod = ""
c.httpClient.SetAuthScheme("")
c.httpClient.SetAuthToken("")
}
func (c *InfisicalClient) setPlainAccessToken(accessToken string) {
c.mu.Lock()
defer c.mu.Unlock()
c.authMethod = util.ACCESS_TOKEN
c.httpClient.SetAuthScheme("Bearer")
c.httpClient.SetAuthToken(accessToken)
c.tokenDetails.AccessToken = accessToken
c.credential = models.AccessTokenCredential{AccessToken: accessToken}
}
func NewInfisicalClient(context context.Context, config Config) InfisicalClientInterface {
logger := setupLogger(config.LogLevel, config.LogWriter)
client := &InfisicalClient{
logger: logger,
}
setDefaults(&config)
client.UpdateConfiguration(config) // set httpClient and config
// add interfaces here
client.secrets = NewSecrets(client)
client.folders = NewFolders(client)
client.auth = NewAuth(client)
client.dynamicSecrets = NewDynamicSecrets(client)
client.kms = NewKms(client)
client.ssh = NewSsh(client)
if config.CacheExpiryInSeconds != 0 {
// hard limit set at 1000 cache items until forced eviction
client.cache = expirable.NewLRU[string, interface{}](1000, nil, time.Second*time.Duration(config.CacheExpiryInSeconds))
}
if autoTokenRefreshEnabled(config) {
go client.handleTokenLifeCycle(context)
}
return client
}
func (c *InfisicalClient) UpdateConfiguration(config Config) {
c.mu.Lock()
defer c.mu.Unlock()
setDefaults(&config)
config.SiteUrl = util.AppendAPIEndpoint(config.SiteUrl)
c.config = config
if c.httpClient == nil {
c.httpClient = resty.New().
SetHeader("User-Agent", config.UserAgent).
SetBaseURL(config.SiteUrl)
maxRetries := 3
maxWaitTime := 30 * time.Second
if config.RetryRequestsConfig != nil && config.RetryRequestsConfig.ExponentialBackoff != nil {
maxRetries = config.RetryRequestsConfig.ExponentialBackoff.MaxRetries
maxWaitTime = 10 * time.Minute
}
c.httpClient.SetRetryCount(maxRetries).
SetRetryWaitTime(1 * time.Second).
SetRetryMaxWaitTime(maxWaitTime).
SetRetryAfter(func(rc *resty.Client, r *resty.Response) (time.Duration, error) {
if config.RetryRequestsConfig != nil && config.RetryRequestsConfig.ExponentialBackoff != nil {
delay := config.RetryRequestsConfig.ExponentialBackoff.GetDelay(r.Request.Attempt)
if !config.SilentMode {
util.PrintWarning(c.logger, fmt.Sprintf("Request failed, [url=%s] [status=%d] [method=%s]\nRetrying in %s (attempt %d)", r.Request.URL, r.StatusCode(), r.Request.Method, delay.String(), r.Request.Attempt))
}
return delay, nil
}
attempt := r.Request.Attempt + 1
if attempt <= 0 {
attempt = 1
}
waitTime := math.Min(float64(rc.RetryWaitTime)*math.Pow(2, float64(attempt-1)), float64(rc.RetryMaxWaitTime))
// Add jitter of +/-20%
jitterFactor := 0.8 + (rand.Float64() * 0.4)
waitTime = waitTime * jitterFactor
waitDuration := time.Duration(waitTime)
return waitDuration, nil
}).
AddRetryCondition(func(r *resty.Response, err error) bool {
// don't retry if there's no error or it's a timeout
if errors.Is(err, context.DeadlineExceeded) {
return false
}
if err == nil && r == nil {
return false
}
if config.RetryRequestsConfig != nil && config.RetryRequestsConfig.ExponentialBackoff != nil {
if (r != nil && r.IsError()) || err != nil {
return r.Request.Attempt <= config.RetryRequestsConfig.ExponentialBackoff.MaxRetries
}
}
networkErrors := []string{
"connection refused",
"connection reset",
"network",
"connection",
"no such host",
"i/o timeout",
"dial tcp",
"broken pipe",
"wsaetimeout",
"wsaeconnreset",
"econnreset",
"econnrefused",
"ehostunreach",
"enetunreach",
}
isConditionMet := false
var netErr net.Error
if errors.As(err, &netErr) {
return true
}
if err != nil {
for _, netErr := range networkErrors {
errMsg := err.Error()
if strings.Contains(strings.ToLower(errMsg), netErr) {
isConditionMet = true
break
}
}
}
return isConditionMet
})
// OnBeforeRequest hook to validate and refresh token before each request.
// This is a safety net to catch cases where the background token lifecycle
// goroutine might miss a refresh window due to timing issues (GC pauses,
// CPU contention, etc.). Most requests will not trigger a refresh here
// because the background goroutine handles proactive token management.
if autoTokenRefreshEnabled(config) {
c.httpClient.OnBeforeRequest(c.beforeRequestAuthInterceptor)
}
} else {
c.httpClient.
SetHeader("User-Agent", config.UserAgent).
SetBaseURL(config.SiteUrl)
}
if len(config.CustomHeaders) > 0 {
c.httpClient.SetHeaders(config.CustomHeaders)
}
if config.CaCertificate != "" {
caCertPool, err := x509.SystemCertPool()
if err != nil && !config.SilentMode {
util.PrintWarning(c.logger, fmt.Sprintf("failed to load system root CA pool: %v", err))
}
if ok := caCertPool.AppendCertsFromPEM([]byte(config.CaCertificate)); !ok && !config.SilentMode {
util.PrintWarning(c.logger, "failed to append CA certificate")
}
tlsConfig := &tls.Config{
RootCAs: caCertPool,
}
c.httpClient.SetTLSClientConfig(tlsConfig)
}
}
func (c *InfisicalClient) Secrets() SecretsInterface {
return c.secrets
}
func (c *InfisicalClient) Folders() FoldersInterface {
return c.folders
}
func (c *InfisicalClient) Auth() AuthInterface {
return c.auth
}
func (c *InfisicalClient) DynamicSecrets() DynamicSecretsInterface {
return c.dynamicSecrets
}
func (c *InfisicalClient) Kms() KmsInterface {
return c.kms
}
func (c *InfisicalClient) Ssh() SshInterface {
return c.ssh
}
func (c *InfisicalClient) handleTokenLifeCycle(context context.Context) {
var warningPrinted = false
for {
select {
case <-context.Done():
return // The context has been cancelled, clean up and return from the loop to stop the goroutine
default:
c.mu.RLock()
config := c.config
authMethod := c.authMethod
tokenDetails := c.tokenDetails
c.mu.RUnlock()
if autoTokenRefreshEnabled(config) && authMethod != "" && authMethod != util.ACCESS_TOKEN {
// Print warning once for short TTLs
if !config.SilentMode && !warningPrinted && tokenDetails.AccessTokenMaxTTL != 0 && tokenDetails.ExpiresIn != 0 {
if tokenDetails.AccessTokenMaxTTL < 60 || tokenDetails.ExpiresIn < 60 {
util.PrintWarning(c.logger, "Machine Identity access token TTL or max TTL is less than 60 seconds. This may cause excessive API calls, and you may be subject to rate-limits.")
}
warningPrinted = true
}
// Check if token needs refresh (using the same buffer as OnBeforeRequest)
if c.isTokenExpiringSoon(renewalBufferSeconds) {
// Use refreshTokenSynchronously which handles both renewal and re-auth
// Pass false for manualTrigger since this is from the background goroutine
if err := c.refreshTokenSynchronously(false); err != nil {
c.logger.Debug().Msgf("Background token refresh failed: %s", err.Error())
}
// Re-read token details after refresh attempt
c.mu.RLock()
tokenDetails = c.tokenDetails
c.mu.RUnlock()
}
// Calculate sleep time until next check
sleepTime := c.calculateSleepTime(tokenDetails, renewalBufferSeconds)
if err := util.SleepWithContext(context, sleepTime); err != nil && (err == util.ErrContextCanceled || errors.Is(err, util.ErrContextDeadlineExceeded)) {
return
}
} else {
if err := util.SleepWithContext(context, 1*time.Second); err != nil && (err == util.ErrContextCanceled || errors.Is(err, util.ErrContextDeadlineExceeded)) {
return
}
}
}
}
}

View File

@@ -0,0 +1,259 @@
package infisical
import (
"fmt"
"net/http"
"strings"
"time"
"github.com/go-resty/resty/v2"
api "github.com/infisical/go-sdk/packages/api/auth"
"github.com/infisical/go-sdk/packages/models"
"github.com/infisical/go-sdk/packages/util"
)
const renewalBufferSeconds = 5
// isTokenExpiringSoon checks if the token will expire within the given buffer time.
func (c *InfisicalClient) isTokenExpiringSoon(bufferSeconds int64) bool {
c.mu.RLock()
defer c.mu.RUnlock()
// Skip if no auth method or using plain access token (no refresh capability)
if c.authMethod == "" || c.authMethod == util.ACCESS_TOKEN {
return false
}
// Skip if token details are not set
if c.tokenDetails.ExpiresIn == 0 {
return false
}
timeSinceLastFetch := time.Since(c.lastFetchedTime).Seconds()
return timeSinceLastFetch >= float64(c.tokenDetails.ExpiresIn-bufferSeconds)
}
// refreshTokenSynchronously performs a blocking token refresh. This gets called by the onbeforerequest hook and the token lifecycle goroutine.
func (c *InfisicalClient) refreshTokenSynchronously(manualTrigger bool) error {
c.logger.Debug().Msgf("Refreshing token synchronously. Manual trigger: %v", manualTrigger)
// Use TryLock to prevent deadlocks when the refresh operation itself triggers HTTP requests (renewal or re-auth)
// If we can't acquire the lock, another goroutine is already refreshing.
if !c.refreshMu.TryLock() {
c.logger.Debug().Msg("Another refresh is already in progress, skipping")
return nil
}
defer c.refreshMu.Unlock()
// Double-check if refresh is still needed after acquiring the lock
// (another goroutine might have already refreshed)
if !c.isTokenExpiringSoon(renewalBufferSeconds) {
return nil
}
c.mu.RLock()
authMethod := c.authMethod
credential := c.credential
tokenDetails := c.tokenDetails
firstFetchedTime := c.firstFetchedTime
config := c.config
c.mu.RUnlock()
// Check if we need re-auth (approaching max TTL) or can renew
timeSinceFirstFetch := time.Since(firstFetchedTime).Seconds()
timeUntilMaxTTL := float64(tokenDetails.AccessTokenMaxTTL) - timeSinceFirstFetch
// If time until max TTL is less than the token TTL, we need to re-auth
needsReAuth := timeUntilMaxTTL < float64(tokenDetails.ExpiresIn)
c.logger.Debug().Msgf("timeSinceFirstFetch: %f, timeUntilMaxTTL: %f, needsReAuth: %v", timeSinceFirstFetch, timeUntilMaxTTL, needsReAuth)
if needsReAuth {
c.logger.Debug().Msgf("Re-authentication needed. Attempting re-authentication")
err := c.doReAuthentication(authMethod, credential, config)
message := "Re-authentication successful"
if err != nil {
message = fmt.Sprintf("Re-authentication failed. Error: %v", err)
}
c.logger.Debug().Msg(message)
return err
}
// Try renewal first
c.logger.Debug().Msgf("Attempting token renewal")
err := c.doTokenRenewal(tokenDetails.AccessToken, credential, authMethod)
if err != nil {
c.logger.Debug().Msgf("Token renewal failed. Attempting re-authentication as fallback. Error: %v", err)
// Renewal failed, try re-authentication as fallback
if !config.SilentMode {
util.PrintWarning(c.logger, fmt.Sprintf("Token renewal failed during pre-request check: %s. Attempting re-authentication", err.Error()))
}
message := "Re-authentication successful as fallback"
err = c.doReAuthentication(authMethod, credential, config)
if err != nil {
message = fmt.Sprintf("Re-authentication failed as fallback. Error: %v", err)
}
c.logger.Debug().Msg(message)
return err
}
c.logger.Debug().Msgf("Token renewal successful")
return nil
}
// doTokenRenewal attempts to renew the access token.
func (c *InfisicalClient) doTokenRenewal(accessToken string, credential interface{}, authMethod util.AuthMethod) error {
renewedCredential, err := api.CallRenewAccessToken(c.httpClient, api.RenewAccessTokenRequest{AccessToken: accessToken})
if err != nil {
return err
}
c.setAccessToken(renewedCredential, credential, authMethod)
return nil
}
// doReAuthentication performs a full re-authentication using the stored credentials.
func (c *InfisicalClient) doReAuthentication(authMethod util.AuthMethod, credential interface{}, config Config) error {
authStrategies := c.getAuthStrategies()
strategy, exists := authStrategies[authMethod]
if !exists {
return fmt.Errorf("unknown auth method: %s", authMethod)
}
newToken, err := strategy(credential)
if err != nil {
if !config.SilentMode {
util.PrintWarning(c.logger, fmt.Sprintf("Re-authentication failed during pre-request check: %s", err.Error()))
}
return err
}
c.setAccessToken(newToken, credential, authMethod)
c.mu.Lock()
c.firstFetchedTime = time.Now()
c.mu.Unlock()
return nil
}
// calculateSleepTime determines how long to sleep before the next token refresh check
func (c *InfisicalClient) calculateSleepTime(tokenDetails MachineIdentityCredential, bufferSeconds int64) time.Duration {
if tokenDetails.ExpiresIn == 0 {
return 1 * time.Second
}
c.mu.RLock()
timeSinceLastFetch := time.Since(c.lastFetchedTime).Seconds()
c.mu.RUnlock()
timeUntilExpiry := float64(tokenDetails.ExpiresIn) - timeSinceLastFetch - float64(bufferSeconds)
if timeUntilExpiry <= 0 {
return 1 * time.Second
}
return time.Duration(timeUntilExpiry) * time.Second
}
// getAuthStrategies returns the map of authentication strategies
func (c *InfisicalClient) getAuthStrategies() map[util.AuthMethod]func(cred interface{}) (credential MachineIdentityCredential, err error) {
return map[util.AuthMethod]func(cred interface{}) (credential MachineIdentityCredential, err error){
util.UNIVERSAL_AUTH: func(cred interface{}) (credential MachineIdentityCredential, err error) {
if parsedCreds, ok := cred.(models.UniversalAuthCredential); ok {
return c.auth.UniversalAuthLogin(parsedCreds.ClientID, parsedCreds.ClientSecret)
}
return MachineIdentityCredential{}, fmt.Errorf("failed to parse UniversalAuthCredential")
},
util.KUBERNETES: func(cred interface{}) (credential MachineIdentityCredential, err error) {
if parsedCreds, ok := cred.(models.KubernetesCredential); ok {
return c.auth.KubernetesRawServiceAccountTokenLogin(parsedCreds.IdentityID, parsedCreds.ServiceAccountToken)
}
return MachineIdentityCredential{}, fmt.Errorf("failed to parse KubernetesAuthCredential")
},
util.AZURE: func(cred interface{}) (credential MachineIdentityCredential, err error) {
if parsedCreds, ok := cred.(models.AzureCredential); ok {
if parsedCreds.ClientID != "" {
return c.auth.WithAzureClientID(parsedCreds.ClientID).AzureAuthLogin(parsedCreds.IdentityID, parsedCreds.Resource)
}
return c.auth.AzureAuthLogin(parsedCreds.IdentityID, parsedCreds.Resource)
}
return MachineIdentityCredential{}, fmt.Errorf("failed to parse AzureAuthCredential")
},
util.GCP_ID_TOKEN: func(cred interface{}) (credential MachineIdentityCredential, err error) {
if parsedCreds, ok := cred.(models.GCPIDTokenCredential); ok {
return c.auth.GcpIdTokenAuthLogin(parsedCreds.IdentityID)
}
return MachineIdentityCredential{}, fmt.Errorf("failed to parse GCPIDTokenCredential")
},
util.GCP_IAM: func(cred interface{}) (credential MachineIdentityCredential, err error) {
if parsedCreds, ok := cred.(models.GCPIAMCredential); ok {
return c.auth.GcpIamAuthLogin(parsedCreds.IdentityID, parsedCreds.ServiceAccountKeyFilePath)
}
return MachineIdentityCredential{}, fmt.Errorf("failed to parse GCPIAMCredential")
},
util.AWS_IAM: func(cred interface{}) (credential MachineIdentityCredential, err error) {
if parsedCreds, ok := cred.(models.AWSIAMCredential); ok {
return c.auth.AwsIamAuthLogin(parsedCreds.IdentityID)
}
return MachineIdentityCredential{}, fmt.Errorf("failed to parse AWSIAMCredential")
},
util.JWT_AUTH: func(cred interface{}) (credential MachineIdentityCredential, err error) {
if parsedCreds, ok := cred.(models.JWTCredential); ok {
return c.auth.JwtAuthLogin(parsedCreds.IdentityID, parsedCreds.JWT)
}
return MachineIdentityCredential{}, fmt.Errorf("failed to parse JWTCredential")
},
util.LDAP_AUTH: func(cred interface{}) (credential MachineIdentityCredential, err error) {
if parsedCreds, ok := cred.(models.LDAPCredential); ok {
return c.auth.LdapAuthLogin(parsedCreds.IdentityID, parsedCreds.Username, parsedCreds.Password)
}
return MachineIdentityCredential{}, fmt.Errorf("failed to parse LDAPCredential")
},
util.OCI_AUTH: func(cred interface{}) (credential MachineIdentityCredential, err error) {
if parsedCreds, ok := cred.(models.OCICredential); ok {
return c.auth.OciAuthLogin(OciAuthLoginOptions{
IdentityID: parsedCreds.IdentityID,
PrivateKey: parsedCreds.PrivateKey,
Fingerprint: parsedCreds.Fingerprint,
UserID: parsedCreds.UserID,
TenancyID: parsedCreds.TenancyID,
Region: parsedCreds.Region,
Passphrase: parsedCreds.Passphrase,
})
}
return MachineIdentityCredential{}, fmt.Errorf("failed to parse OCICredential")
},
}
}
func (c *InfisicalClient) beforeRequestAuthInterceptor(client *resty.Client, req *resty.Request) error {
// skip auth endpoints to prevent infinite loops.
// note(daniel): req.URL contains just the path ("/v1/auth/..."), not the full URL with base.
// the base URL has /api appended, but that's not part of req.URL at this point.
if strings.Contains(req.URL, "/v1/auth/") && req.Method == http.MethodPost {
return nil
}
// Check if token is expired or will expire within 5 seconds
if c.isTokenExpiringSoon(renewalBufferSeconds) {
if err := c.refreshTokenSynchronously(true); err != nil {
// Don't fail the request on refresh error, we let the request fail with 401 as it normally would.
// logging is already done within refreshTokenSynchronously
return nil
}
c.mu.RLock()
newToken := c.tokenDetails.AccessToken
c.mu.RUnlock()
if newToken != "" {
req.SetAuthToken(newToken)
}
}
return nil
}

115
vendor/github.com/infisical/go-sdk/dynamic_secrets.go generated vendored Normal file
View File

@@ -0,0 +1,115 @@
package infisical
import (
api "github.com/infisical/go-sdk/packages/api/dynamic_secrets"
"github.com/infisical/go-sdk/packages/models"
)
type ListDynamicSecretLeasesOptions = api.ListDynamicSecretLeaseV1Request
type CreateDynamicSecretLeaseOptions = api.CreateDynamicSecretLeaseV1Request
type DeleteDynamicSecretLeaseOptions = api.DeleteDynamicSecretLeaseV1Request
type GetDynamicSecretLeaseByIdOptions = api.GetDynamicSecretLeaseByIdV1Request
type RenewDynamicSecretLeaseOptions = api.RenewDynamicSecretLeaseV1Request
type ListDynamicSecretsRootCredentialsOptions = api.ListDynamicSecretsV1Request
type GetDynamicSecretRootCredentialByNameOptions = api.GetDynamicSecretByNameV1Request
type DynamicSecretsInterface interface {
List(options ListDynamicSecretsRootCredentialsOptions) ([]models.DynamicSecret, error)
GetByName(options GetDynamicSecretRootCredentialByNameOptions) (models.DynamicSecret, error)
Leases() DynamicSecretLeaseInterface
}
type DynamicSecretLeaseInterface interface {
List(options ListDynamicSecretLeasesOptions) ([]models.DynamicSecretLease, error)
Create(options CreateDynamicSecretLeaseOptions) (map[string]any, models.DynamicSecret, models.DynamicSecretLease, error)
GetById(options GetDynamicSecretLeaseByIdOptions) (models.DynamicSecretLeaseWithDynamicSecret, error)
DeleteById(options DeleteDynamicSecretLeaseOptions) (models.DynamicSecretLease, error)
RenewById(options RenewDynamicSecretLeaseOptions) (models.DynamicSecretLease, error)
}
type DynamicSecrets struct {
client *InfisicalClient
leases DynamicSecretLeaseInterface
}
func (f *DynamicSecrets) List(options ListDynamicSecretsRootCredentialsOptions) ([]models.DynamicSecret, error) {
res, err := api.CallListDynamicSecretsV1(f.client.httpClient, options)
if err != nil {
return nil, err
}
return res.DynamicSecrets, nil
}
func (f *DynamicSecrets) GetByName(options GetDynamicSecretRootCredentialByNameOptions) (models.DynamicSecret, error) {
res, err := api.CallGetDynamicSecretByNameV1(f.client.httpClient, options)
if err != nil {
return models.DynamicSecret{}, err
}
return res.DynamicSecret, nil
}
func (f *DynamicSecrets) Leases() DynamicSecretLeaseInterface {
return f.leases
}
type DynamicSecretLeases struct {
client *InfisicalClient
}
func (f *DynamicSecretLeases) List(options ListDynamicSecretLeasesOptions) ([]models.DynamicSecretLease, error) {
res, err := api.CallListDynamicSecretLeaseV1(f.client.httpClient, options)
if err != nil {
return nil, err
}
return res.Leases, nil
}
func (f *DynamicSecretLeases) Create(options CreateDynamicSecretLeaseOptions) (map[string]any, models.DynamicSecret, models.DynamicSecretLease, error) {
res, err := api.CallCreateDynamicSecretLeaseV1(f.client.httpClient, options)
if err != nil {
return nil, models.DynamicSecret{}, models.DynamicSecretLease{}, err
}
return res.Data, res.DynamicSecret, res.Lease, nil
}
func (f *DynamicSecretLeases) GetById(options GetDynamicSecretLeaseByIdOptions) (models.DynamicSecretLeaseWithDynamicSecret, error) {
res, err := api.CallGetByDynamicSecretByIdLeaseV1(f.client.httpClient, options)
if err != nil {
return models.DynamicSecretLeaseWithDynamicSecret{}, err
}
return res.Lease, nil
}
func (f *DynamicSecretLeases) DeleteById(options DeleteDynamicSecretLeaseOptions) (models.DynamicSecretLease, error) {
res, err := api.CallDeleteDynamicSecretLeaseV1(f.client.httpClient, options)
if err != nil {
return models.DynamicSecretLease{}, err
}
return res.Lease, nil
}
func (f *DynamicSecretLeases) RenewById(options RenewDynamicSecretLeaseOptions) (models.DynamicSecretLease, error) {
res, err := api.CallRenewDynamicSecretLeaseV1(f.client.httpClient, options)
if err != nil {
return models.DynamicSecretLease{}, err
}
return res.Lease, nil
}
func NewDynamicSecrets(client *InfisicalClient) DynamicSecretsInterface {
return &DynamicSecrets{client: client, leases: &DynamicSecretLeases{client: client}}
}

66
vendor/github.com/infisical/go-sdk/folders.go generated vendored Normal file
View File

@@ -0,0 +1,66 @@
package infisical
import (
api "github.com/infisical/go-sdk/packages/api/folders"
"github.com/infisical/go-sdk/packages/models"
)
type ListFoldersOptions = api.ListFoldersV1Request
type UpdateFolderOptions = api.UpdateFolderV1Request
type CreateFolderOptions = api.CreateFolderV1Request
type DeleteFolderOptions = api.DeleteFolderV1Request
type FoldersInterface interface {
List(options ListFoldersOptions) ([]models.Folder, error)
Update(options UpdateFolderOptions) (models.Folder, error)
Create(options CreateFolderOptions) (models.Folder, error)
Delete(options DeleteFolderOptions) (models.Folder, error)
}
type Folders struct {
client *InfisicalClient
}
func (f *Folders) List(options ListFoldersOptions) ([]models.Folder, error) {
res, err := api.CallListFoldersV1(f.client.httpClient, options)
if err != nil {
return nil, err
}
return res.Folders, nil
}
func (f *Folders) Update(options UpdateFolderOptions) (models.Folder, error) {
res, err := api.CallUpdateFolderV1(f.client.httpClient, options)
if err != nil {
return models.Folder{}, err
}
return res.Folder, nil
}
func (f *Folders) Create(options CreateFolderOptions) (models.Folder, error) {
res, err := api.CallCreateFolderV1(f.client.httpClient, options)
if err != nil {
return models.Folder{}, err
}
return res.Folder, nil
}
func (f *Folders) Delete(options DeleteFolderOptions) (models.Folder, error) {
res, err := api.CallDeleteFolderV1(f.client.httpClient, options)
if err != nil {
return models.Folder{}, err
}
return res.Folder, nil
}
func NewFolders(client *InfisicalClient) FoldersInterface {
return &Folders{client: client}
}

177
vendor/github.com/infisical/go-sdk/kms.go generated vendored Normal file
View File

@@ -0,0 +1,177 @@
package infisical
import (
"encoding/base64"
api "github.com/infisical/go-sdk/packages/api/kms"
)
// Options
type KmsEncryptDataOptions = api.KmsEncryptDataV1Request
type KmsDecryptDataOptions = api.KmsDecryptDataV1Request
type KmsSignDataOptions = api.KmsSignDataV1Request
type KmsVerifyDataOptions = api.KmsVerifyDataV1Request
type KmsListSigningAlgorithmsOptions = api.KmsListSigningAlgorithmsV1Request
type KmsGetPublicKeyOptions = api.KmsGetPublicKeyV1Request
type KmsCreateKeyOptions = api.KmsCreateKeyV1Request
type KmsDeleteKeyOptions = api.KmsDeleteKeyV1Request
type KmsGetKeyByNameOptions = api.KmsGetKeyByNameV1Request
// Results
type KmsVerifyDataResult = api.KmsVerifyDataV1Response
type KmsSignDataResult = api.KmsSignDataV1Response
type KmsCreateKeyResult = api.KmsKey
type KmsDeleteKeyResult = api.KmsKey
type KmsGetKeyResult = api.KmsKey
type KmsKeysInterface interface {
Create(options KmsCreateKeyOptions) (KmsCreateKeyResult, error)
Delete(options KmsDeleteKeyOptions) (KmsDeleteKeyResult, error)
GetByName(options KmsGetKeyByNameOptions) (KmsGetKeyResult, error)
}
type KmsSigningInterface interface {
SignData(options KmsSignDataOptions) ([]byte, error)
VerifyData(options KmsVerifyDataOptions) (KmsVerifyDataResult, error)
ListSigningAlgorithms(options KmsListSigningAlgorithmsOptions) ([]string, error)
GetPublicKey(options KmsGetPublicKeyOptions) (string, error)
}
type KmsInterface interface {
EncryptData(options KmsEncryptDataOptions) (string, error)
DecryptData(options KmsDecryptDataOptions) (string, error)
Keys() KmsKeysInterface
Signing() KmsSigningInterface
}
type Kms struct {
client *InfisicalClient
keys *KmsKeys
signing *KmsSigning
}
type KmsKeys struct {
client *InfisicalClient
}
type KmsSigning struct {
client *InfisicalClient
}
func (k *KmsKeys) Create(options KmsCreateKeyOptions) (KmsCreateKeyResult, error) {
res, err := api.CallKmsCreateKeyV1(k.client.httpClient, options)
if err != nil {
return KmsCreateKeyResult{}, err
}
return res.Key, nil
}
func (k *KmsKeys) Delete(options KmsDeleteKeyOptions) (KmsDeleteKeyResult, error) {
res, err := api.CallKmsDeleteKeyV1(k.client.httpClient, options)
if err != nil {
return KmsDeleteKeyResult{}, err
}
return res.Key, nil
}
func (k *KmsKeys) GetByName(options KmsGetKeyByNameOptions) (KmsGetKeyResult, error) {
res, err := api.CallKmsGetKeyByNameV1(k.client.httpClient, options)
if err != nil {
return KmsGetKeyResult{}, err
}
return res.Key, nil
}
func (k *KmsSigning) SignData(options KmsSignDataOptions) ([]byte, error) {
res, err := api.CallKmsSignDataV1(k.client.httpClient, options)
if err != nil {
return nil, err
}
return base64.StdEncoding.DecodeString(res.Signature)
}
func (k *KmsSigning) VerifyData(options KmsVerifyDataOptions) (KmsVerifyDataResult, error) {
res, err := api.CallKmsVerifyDataV1(k.client.httpClient, options)
if err != nil {
return KmsVerifyDataResult{}, err
}
return res, nil
}
func (k *KmsSigning) ListSigningAlgorithms(options KmsListSigningAlgorithmsOptions) ([]string, error) {
res, err := api.CallKmsGetSigningAlgorithmsV1(k.client.httpClient, options)
if err != nil {
return []string{}, err
}
return res.SigningAlgorithms, nil
}
func (k *KmsSigning) GetPublicKey(options KmsGetPublicKeyOptions) (string, error) {
res, err := api.CallKmsGetPublicKeyV1(k.client.httpClient, options)
if err != nil {
return "", err
}
return res.PublicKey, nil
}
func (f *Kms) EncryptData(options KmsEncryptDataOptions) (string, error) {
options.Plaintext = base64.StdEncoding.EncodeToString([]byte(options.Plaintext))
res, err := api.CallKmsEncryptDataV1(f.client.httpClient, options)
if err != nil {
return "", err
}
return res.Ciphertext, nil
}
func (f *Kms) DecryptData(options KmsDecryptDataOptions) (string, error) {
res, err := api.CallKmsDecryptDataV1(f.client.httpClient, options)
if err != nil {
return "", err
}
decodedPlaintext, err := base64.StdEncoding.DecodeString(res.Plaintext)
if err != nil {
return "", err
}
return string(decodedPlaintext), nil
}
func (f *Kms) Keys() KmsKeysInterface {
return &KmsKeys{client: f.client}
}
func (f *Kms) Signing() KmsSigningInterface {
return &KmsSigning{client: f.client}
}
func NewKms(client *InfisicalClient) KmsInterface {
return &Kms{
client: client,
keys: &KmsKeys{client: client},
signing: &KmsSigning{client: client},
}
}

26
vendor/github.com/infisical/go-sdk/models.go generated vendored Normal file
View File

@@ -0,0 +1,26 @@
package infisical
import (
api "github.com/infisical/go-sdk/packages/api/auth"
"github.com/infisical/go-sdk/packages/errors"
"github.com/infisical/go-sdk/packages/models"
)
type OciAuthLoginOptions struct {
IdentityID string
PrivateKey string
Fingerprint string
UserID string
TenancyID string
Region string
Passphrase *string
}
type MachineIdentityCredential = api.MachineIdentityAuthLoginResponse
type Secret = models.Secret
type SecretImport = models.SecretImport
type APIError = errors.APIError
type RequestError = errors.RequestError
type NotModifiedError = errors.NotModifiedError

View File

@@ -0,0 +1,31 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callAWSIamAuthLoginOperation = "CallAWSIamAuthLogin"
func CallAWSIamAuthLogin(httpClient *resty.Client, request AwsIamAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
var responseData MachineIdentityAuthLoginResponse
clonedClient := httpClient.Clone()
clonedClient.SetAuthToken("")
clonedClient.SetAuthScheme("")
response, err := clonedClient.R().
SetResult(&responseData).
SetBody(request).
Post("/v1/auth/aws-auth/login")
if err != nil {
return MachineIdentityAuthLoginResponse{}, errors.NewRequestError(callAWSIamAuthLoginOperation, err)
}
if response.IsError() {
return MachineIdentityAuthLoginResponse{}, errors.NewAPIErrorWithResponse(callAWSIamAuthLoginOperation, response)
}
return responseData, nil
}

View File

@@ -0,0 +1,31 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const azureAuthLoginOperation = "CallAzureAuthLogin"
func CallAzureAuthLogin(httpClient *resty.Client, request AzureAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
var responseData MachineIdentityAuthLoginResponse
clonedClient := httpClient.Clone()
clonedClient.SetAuthToken("")
clonedClient.SetAuthScheme("")
response, err := clonedClient.R().
SetResult(&responseData).
SetBody(request).
Post("/v1/auth/azure-auth/login")
if err != nil {
return MachineIdentityAuthLoginResponse{}, errors.NewRequestError(azureAuthLoginOperation, err)
}
if response.IsError() {
return MachineIdentityAuthLoginResponse{}, errors.NewAPIErrorWithResponse(azureAuthLoginOperation, response)
}
return responseData, nil
}

View File

@@ -0,0 +1,31 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callGCPAuthLoginOperation = "CallGCPAuthLogin"
func CallGCPAuthLogin(httpClient *resty.Client, request GCPAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
var responseData MachineIdentityAuthLoginResponse
clonedClient := httpClient.Clone()
clonedClient.SetAuthToken("")
clonedClient.SetAuthScheme("")
response, err := clonedClient.R().
SetResult(&responseData).
SetBody(request).
Post("/v1/auth/gcp-auth/login")
if err != nil {
return MachineIdentityAuthLoginResponse{}, errors.NewRequestError(callGCPAuthLoginOperation, err)
}
if response.IsError() {
return MachineIdentityAuthLoginResponse{}, errors.NewAPIErrorWithResponse(callGCPAuthLoginOperation, response)
}
return responseData, nil
}

View File

@@ -0,0 +1,31 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callJwtAuthLoginOperation = "CallJwtAuthLogin"
func CallJwtAuthLogin(httpClient *resty.Client, request JwtAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
var responseData MachineIdentityAuthLoginResponse
clonedClient := httpClient.Clone()
clonedClient.SetAuthToken("")
clonedClient.SetAuthScheme("")
response, err := clonedClient.R().
SetResult(&responseData).
SetBody(request).
Post("/v1/auth/jwt-auth/login")
if err != nil {
return responseData, errors.NewRequestError(callJwtAuthLoginOperation, err)
}
if response.IsError() {
return responseData, errors.NewAPIErrorWithResponse(callJwtAuthLoginOperation, response)
}
return responseData, nil
}

View File

@@ -0,0 +1,31 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callKubernetesAuthLoginOperation = "CallKubernetesAuthLogin"
func CallKubernetesAuthLogin(httpClient *resty.Client, request KubernetesAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
var responseData MachineIdentityAuthLoginResponse
clonedClient := httpClient.Clone()
clonedClient.SetAuthToken("")
clonedClient.SetAuthScheme("")
response, err := clonedClient.R().
SetResult(&responseData).
SetBody(request).
Post("/v1/auth/kubernetes-auth/login")
if err != nil {
return MachineIdentityAuthLoginResponse{}, errors.NewRequestError(callKubernetesAuthLoginOperation, err)
}
if response.IsError() {
return MachineIdentityAuthLoginResponse{}, errors.NewAPIErrorWithResponse(callKubernetesAuthLoginOperation, response)
}
return responseData, nil
}

View File

@@ -0,0 +1,31 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callLdapAuthLoginOperation = "CallLdapAuthLogin"
func CallLdapAuthLogin(httpClient *resty.Client, request LdapAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
var responseData MachineIdentityAuthLoginResponse
clonedClient := httpClient.Clone()
clonedClient.SetAuthToken("")
clonedClient.SetAuthScheme("")
response, err := clonedClient.R().
SetResult(&responseData).
SetBody(request).
Post("/v1/auth/ldap-auth/login")
if err != nil {
return MachineIdentityAuthLoginResponse{}, errors.NewRequestError(callLdapAuthLoginOperation, err)
}
if response.IsError() {
return MachineIdentityAuthLoginResponse{}, errors.NewAPIErrorWithResponse(callLdapAuthLoginOperation, response)
}
return responseData, nil
}

View File

@@ -0,0 +1,82 @@
package api
// JWT auth:
type JwtAuthLoginRequest struct {
IdentityID string `json:"identityId"`
JWT string `json:"jwt"`
OrganizationSlug string `json:"organizationSlug,omitempty"`
}
// Revoke access token:
type RevokeAccessTokenRequest struct {
AccessToken string `json:"accessToken"`
}
type RevokeAccessTokenResponse struct {
Message string `json:"message"`
}
// Universal auth:
type UniversalAuthLoginRequest struct {
ClientID string `json:"clientId"`
ClientSecret string `json:"clientSecret"`
OrganizationSlug string `json:"organizationSlug,omitempty"`
}
// Kubernetes auth:
type KubernetesAuthLoginRequest struct {
IdentityID string `json:"identityId"`
JWT string `json:"jwt"`
OrganizationSlug string `json:"organizationSlug,omitempty"`
}
type AzureAuthLoginRequest struct {
IdentityID string `json:"identityId"`
JWT string `json:"jwt"`
OrganizationSlug string `json:"organizationSlug,omitempty"`
}
type AwsIamAuthLoginRequest struct {
HTTPRequestMethod string `json:"iamHttpRequestMethod"`
IamRequestBody string `json:"iamRequestBody"`
IamRequestHeaders string `json:"iamRequestHeaders"`
IdentityId string `json:"identityId"`
OrganizationSlug string `json:"organizationSlug,omitempty"`
}
type GCPAuthLoginRequest struct {
IdentityID string `json:"identityId"`
JWT string `json:"jwt"`
OrganizationSlug string `json:"organizationSlug,omitempty"`
}
type OidcAuthLoginRequest struct {
IdentityID string `json:"identityId"`
JWT string `json:"jwt"`
OrganizationSlug string `json:"organizationSlug,omitempty"`
}
type MachineIdentityAuthLoginResponse struct {
AccessToken string `json:"accessToken"`
ExpiresIn int64 `json:"expiresIn"`
AccessTokenMaxTTL int64 `json:"accessTokenMaxTTL"`
TokenType string `json:"tokenType"`
}
type RenewAccessTokenRequest struct {
AccessToken string `json:"accessToken"`
}
type OciAuthLoginRequest struct {
IdentityID string `json:"identityId"`
UserOcid string `json:"userOcid"`
Headers map[string]string `json:"headers"`
OrganizationSlug string `json:"organizationSlug,omitempty"`
}
type LdapAuthLoginRequest struct {
IdentityID string `json:"identityId"`
Username string `json:"username"`
Password string `json:"password"`
OrganizationSlug string `json:"organizationSlug,omitempty"`
}

View File

@@ -0,0 +1,31 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callOciAuthLoginOperation = "CallOciAuthLogin"
func CallOciAuthLogin(httpClient *resty.Client, request OciAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
var responseData MachineIdentityAuthLoginResponse
clonedClient := httpClient.Clone()
clonedClient.SetAuthToken("")
clonedClient.SetAuthScheme("")
response, err := clonedClient.R().
SetResult(&responseData).
SetBody(request).
Post("/v1/auth/oci-auth/login")
if err != nil {
return MachineIdentityAuthLoginResponse{}, errors.NewRequestError(callOciAuthLoginOperation, err)
}
if response.IsError() {
return MachineIdentityAuthLoginResponse{}, errors.NewAPIErrorWithResponse(callOciAuthLoginOperation, response)
}
return responseData, nil
}

View File

@@ -0,0 +1,31 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callOidcAuthLoginOperation = "CallOidcAuthLogin"
func CallOidcAuthLogin(httpClient *resty.Client, request OidcAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
var responseData MachineIdentityAuthLoginResponse
clonedClient := httpClient.Clone()
clonedClient.SetAuthToken("")
clonedClient.SetAuthScheme("")
response, err := clonedClient.R().
SetResult(&responseData).
SetBody(request).
Post("/v1/auth/oidc-auth/login")
if err != nil {
return MachineIdentityAuthLoginResponse{}, errors.NewRequestError(callOidcAuthLoginOperation, err)
}
if response.IsError() {
return MachineIdentityAuthLoginResponse{}, errors.NewAPIErrorWithResponse(callOidcAuthLoginOperation, response)
}
return responseData, nil
}

View File

@@ -0,0 +1,31 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callRenewAccessToken = "CallRenewAccessToken"
func CallRenewAccessToken(httpClient *resty.Client, request RenewAccessTokenRequest) (credential MachineIdentityAuthLoginResponse, e error) {
var responseData MachineIdentityAuthLoginResponse
clonedClient := httpClient.Clone()
clonedClient.SetAuthToken("")
clonedClient.SetAuthScheme("")
response, err := clonedClient.R().
SetResult(&responseData).
SetBody(request).
Post("/v1/auth/token/renew")
if err != nil {
return responseData, errors.NewRequestError(callRenewAccessToken, err)
}
if response.IsError() {
return responseData, errors.NewAPIErrorWithResponse(callRenewAccessToken, response)
}
return responseData, nil
}

View File

@@ -0,0 +1,27 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callRevokeAccessTokenOperation = "CallRevokeAccessToken"
func CallRevokeAccessToken(httpClient *resty.Client, request RevokeAccessTokenRequest) (RevokeAccessTokenResponse, error) {
var responseData RevokeAccessTokenResponse
response, err := httpClient.R().
SetResult(&responseData).
SetBody(request).
Post("/v1/auth/token/revoke")
if err != nil {
return responseData, errors.NewRequestError(callRevokeAccessTokenOperation, err)
}
if response.IsError() {
return responseData, errors.NewAPIErrorWithResponse(callRevokeAccessTokenOperation, response)
}
return responseData, nil
}

View File

@@ -0,0 +1,31 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callUniversalAuthLoginOperation = "CallUniversalAuthLogin"
func CallUniversalAuthLogin(httpClient *resty.Client, request UniversalAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
var responseData MachineIdentityAuthLoginResponse
clonedClient := httpClient.Clone()
clonedClient.SetAuthToken("")
clonedClient.SetAuthScheme("")
response, err := clonedClient.R().
SetResult(&responseData).
SetBody(request).
Post("/v1/auth/universal-auth/login")
if err != nil {
return responseData, errors.NewRequestError(callUniversalAuthLoginOperation, err)
}
if response.IsError() {
return responseData, errors.NewAPIErrorWithResponse(callUniversalAuthLoginOperation, response)
}
return responseData, nil
}

View File

@@ -0,0 +1,29 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callCreateDynamicSecretLeaseV1Operation = "CallCreateDynamicSecretLeaseV1"
func CallCreateDynamicSecretLeaseV1(httpClient *resty.Client, request CreateDynamicSecretLeaseV1Request) (CreateDynamicSecretLeaseV1Response, error) {
createResponse := CreateDynamicSecretLeaseV1Response{}
req := httpClient.R().
SetResult(&createResponse).
SetBody(request)
res, err := req.Post("/v1/dynamic-secrets/leases")
if err != nil {
return CreateDynamicSecretLeaseV1Response{}, errors.NewRequestError(callCreateDynamicSecretLeaseV1Operation, err)
}
if res.IsError() {
return CreateDynamicSecretLeaseV1Response{}, errors.NewAPIErrorWithResponse(callCreateDynamicSecretLeaseV1Operation, res)
}
return createResponse, nil
}

View File

@@ -0,0 +1,29 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callDeleteDynamicSecretLeaseV1Operation = "CallDeleteDynamicSecretLeaseV1"
func CallDeleteDynamicSecretLeaseV1(httpClient *resty.Client, request DeleteDynamicSecretLeaseV1Request) (DeleteDynamicSecretLeaseV1Response, error) {
deleteResponse := DeleteDynamicSecretLeaseV1Response{}
req := httpClient.R().
SetResult(&deleteResponse).
SetBody(request)
res, err := req.Delete("/v1/dynamic-secrets/leases/" + request.LeaseId)
if err != nil {
return DeleteDynamicSecretLeaseV1Response{}, errors.NewRequestError(callDeleteDynamicSecretLeaseV1Operation, err)
}
if res.IsError() {
return DeleteDynamicSecretLeaseV1Response{}, errors.NewAPIErrorWithResponse(callDeleteDynamicSecretLeaseV1Operation, res)
}
return deleteResponse, nil
}

View File

@@ -0,0 +1,33 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callGetDynamicSecretLeaseByIdV1Operation = "CallGetDynamicSecretLeaseByIdV1"
func CallGetByDynamicSecretByIdLeaseV1(httpClient *resty.Client, request GetDynamicSecretLeaseByIdV1Request) (GetDynamicSecretLeaseByIdV1Response, error) {
getByIdResponse := GetDynamicSecretLeaseByIdV1Response{}
req := httpClient.R().
SetResult(&getByIdResponse).
SetQueryParams(map[string]string{
"projectSlug": request.ProjectSlug,
"environmentSlug": request.EnvironmentSlug,
"path": request.SecretPath,
})
res, err := req.Get("/v1/dynamic-secrets/leases/" + request.LeaseId)
if err != nil {
return GetDynamicSecretLeaseByIdV1Response{}, errors.NewRequestError(callGetDynamicSecretLeaseByIdV1Operation, err)
}
if res.IsError() {
return GetDynamicSecretLeaseByIdV1Response{}, errors.NewAPIErrorWithResponse(callGetDynamicSecretLeaseByIdV1Operation, res)
}
return getByIdResponse, nil
}

View File

@@ -0,0 +1,32 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callGetDynamicSecretByNameV1Operation = "CallGetDynamicSecretSecretByNameV1"
func CallGetDynamicSecretByNameV1(httpClient *resty.Client, request GetDynamicSecretByNameV1Request) (GetDynamicSecretByNameV1Response, error) {
getByNameResponse := GetDynamicSecretByNameV1Response{}
req := httpClient.R().
SetResult(&getByNameResponse).SetQueryParams(map[string]string{
"projectSlug": request.ProjectSlug,
"environmentSlug": request.EnvironmentSlug,
"path": request.SecretPath,
})
res, err := req.Get("/v1/dynamic-secrets/" + request.DynamicSecretName)
if err != nil {
return GetDynamicSecretByNameV1Response{}, errors.NewRequestError(callGetDynamicSecretByNameV1Operation, err)
}
if res.IsError() {
return GetDynamicSecretByNameV1Response{}, errors.NewAPIErrorWithResponse(callGetDynamicSecretByNameV1Operation, res)
}
return getByNameResponse, nil
}

View File

@@ -0,0 +1,33 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callListDynamicSecretLeaseV1Operation = "CallListDynamicSecretLeaseV1"
func CallListDynamicSecretLeaseV1(httpClient *resty.Client, request ListDynamicSecretLeaseV1Request) (ListDynamicSecretLeaseV1Response, error) {
listResponse := ListDynamicSecretLeaseV1Response{}
req := httpClient.R().
SetResult(&listResponse).
SetQueryParams(map[string]string{
"projectSlug": request.ProjectSlug,
"environmentSlug": request.EnvironmentSlug,
"path": request.SecretPath,
})
res, err := req.Get("/v1/dynamic-secrets/" + request.DynamicSecretName + "/leases")
if err != nil {
return ListDynamicSecretLeaseV1Response{}, errors.NewRequestError(callListDynamicSecretLeaseV1Operation, err)
}
if res.IsError() {
return ListDynamicSecretLeaseV1Response{}, errors.NewAPIErrorWithResponse(callListDynamicSecretLeaseV1Operation, res)
}
return listResponse, nil
}

View File

@@ -0,0 +1,33 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callListDynamicSecretsV1Operation = "CallListDynamicSecretSecretsV1"
func CallListDynamicSecretsV1(httpClient *resty.Client, request ListDynamicSecretsV1Request) (ListDynamicSecretsV1Response, error) {
listDynamicSecretResponse := ListDynamicSecretsV1Response{}
req := httpClient.R().
SetResult(&listDynamicSecretResponse).
SetQueryParams(map[string]string{
"projectSlug": request.ProjectSlug,
"environmentSlug": request.EnvironmentSlug,
"path": request.SecretPath,
})
res, err := req.Get("/v1/dynamic-secrets")
if err != nil {
return ListDynamicSecretsV1Response{}, errors.NewRequestError(callListDynamicSecretsV1Operation, err)
}
if res.IsError() {
return ListDynamicSecretsV1Response{}, errors.NewAPIErrorWithResponse(callListDynamicSecretsV1Operation, res)
}
return listDynamicSecretResponse, nil
}

View File

@@ -0,0 +1,88 @@
package api
import (
"github.com/infisical/go-sdk/packages/models"
)
type CreateDynamicSecretLeaseV1Request struct {
DynamicSecretName string `json:"dynamicSecretName"`
ProjectSlug string `json:"projectSlug"`
TTL string `json:"ttl"`
SecretPath string `json:"path"`
EnvironmentSlug string `json:"environmentSlug"`
Config map[string]any `json:"config"`
}
type CreateDynamicSecretLeaseV1Response struct {
Lease models.DynamicSecretLease `json:"lease"`
DynamicSecret models.DynamicSecret `json:"dynamicSecret"`
Data map[string]any `json:"data"`
}
type DeleteDynamicSecretLeaseV1Request struct {
LeaseId string `json:"leaseId"`
ProjectSlug string `json:"projectSlug"`
SecretPath string `json:"path"`
EnvironmentSlug string `json:"environmentSlug"`
IsForced bool `json:"isForced"`
}
type DeleteDynamicSecretLeaseV1Response struct {
Lease models.DynamicSecretLease `json:"lease"`
}
type RenewDynamicSecretLeaseV1Request struct {
LeaseId string `json:"leaseId"`
TTL string `json:"ttl"`
ProjectSlug string `json:"projectSlug"`
SecretPath string `json:"path"`
EnvironmentSlug string `json:"environmentSlug"`
IsForced bool `json:"isForced"`
}
type RenewDynamicSecretLeaseV1Response struct {
Lease models.DynamicSecretLease `json:"lease"`
}
type GetDynamicSecretLeaseByIdV1Request struct {
LeaseId string `json:"leaseId"`
ProjectSlug string `json:"projectSlug"`
SecretPath string `json:"path"`
EnvironmentSlug string `json:"environmentSlug"`
}
type GetDynamicSecretLeaseByIdV1Response struct {
Lease models.DynamicSecretLeaseWithDynamicSecret `json:"lease"`
}
type ListDynamicSecretLeaseV1Request struct {
DynamicSecretName string `json:"secretName"`
ProjectSlug string `json:"projectSlug"`
SecretPath string `json:"path"`
EnvironmentSlug string `json:"environmentSlug"`
}
type ListDynamicSecretLeaseV1Response struct {
Leases []models.DynamicSecretLease `json:"leases"`
}
type GetDynamicSecretByNameV1Request struct {
DynamicSecretName string `json:"secretName"`
ProjectSlug string `json:"projectSlug"`
SecretPath string `json:"path"`
EnvironmentSlug string `json:"environmentSlug"`
}
type GetDynamicSecretByNameV1Response struct {
DynamicSecret models.DynamicSecret `json:"dynamicSecret"`
}
type ListDynamicSecretsV1Request struct {
ProjectSlug string `json:"projectSlug"`
SecretPath string `json:"path"`
EnvironmentSlug string `json:"environmentSlug"`
}
type ListDynamicSecretsV1Response struct {
DynamicSecrets []models.DynamicSecret `json:"dynamicSecrets"`
}

View File

@@ -0,0 +1,29 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callRenewDynamicSecretLeaseV1Operation = "CallRenewDynamicSecretLeaseV1"
func CallRenewDynamicSecretLeaseV1(httpClient *resty.Client, request RenewDynamicSecretLeaseV1Request) (RenewDynamicSecretLeaseV1Response, error) {
renewResponse := RenewDynamicSecretLeaseV1Response{}
req := httpClient.R().
SetResult(&renewResponse).
SetBody(request)
res, err := req.Post("/v1/dynamic-secrets/leases/" + request.LeaseId + "/renew")
if err != nil {
return RenewDynamicSecretLeaseV1Response{}, errors.NewRequestError(callRenewDynamicSecretLeaseV1Operation, err)
}
if res.IsError() {
return RenewDynamicSecretLeaseV1Response{}, errors.NewAPIErrorWithResponse(callRenewDynamicSecretLeaseV1Operation, res)
}
return renewResponse, nil
}

View File

@@ -0,0 +1,29 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callCreateFolderV1Operation = "CallCreateFolderV1"
func CallCreateFolderV1(httpClient *resty.Client, request CreateFolderV1Request) (CreateFolderV1Response, error) {
createResponse := CreateFolderV1Response{}
req := httpClient.R().
SetResult(&createResponse).
SetBody(request)
res, err := req.Post("/v1/folders")
if err != nil {
return CreateFolderV1Response{}, errors.NewRequestError(callCreateFolderV1Operation, err)
}
if res.IsError() {
return CreateFolderV1Response{}, errors.NewAPIErrorWithResponse(callCreateFolderV1Operation, res)
}
return createResponse, nil
}

View File

@@ -0,0 +1,41 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callDeleteFolderV1Operation = "CallDeleteFolderV1"
func CallDeleteFolderV1(httpClient *resty.Client, request DeleteFolderV1Request) (DeleteFolderV1Response, error) {
deleteResponse := DeleteFolderV1Response{}
// Either folderID or folderName must be provided
var folderIdOrName string
if request.FolderID != "" {
folderIdOrName = request.FolderID
} else if request.FolderName != "" {
folderIdOrName = request.FolderName
} else {
return DeleteFolderV1Response{}, fmt.Errorf("CallDeleteFolderV1: Either folderID or folderName must be provided")
}
req := httpClient.R().
SetResult(&deleteResponse).
SetBody(request)
res, err := req.Delete(fmt.Sprintf("/v1/folders/%s", folderIdOrName))
if err != nil {
return DeleteFolderV1Response{}, errors.NewRequestError(callDeleteFolderV1Operation, err)
}
if res.IsError() {
return DeleteFolderV1Response{}, errors.NewAPIErrorWithResponse(callDeleteFolderV1Operation, res)
}
return deleteResponse, nil
}

View File

@@ -0,0 +1,36 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callListFoldersV1Operation = "CallListFoldersV1"
func CallListFoldersV1(httpClient *resty.Client, request ListFoldersV1Request) (ListFoldersV1Response, error) {
secretsResponse := ListFoldersV1Response{}
queryParams := map[string]string{
"workspaceId": request.ProjectID,
"environment": request.Environment,
}
if request.Path != "" {
queryParams["path"] = request.Path
}
res, err := httpClient.R().
SetResult(&secretsResponse).
SetQueryParams(queryParams).Get("/v1/folders")
if err != nil {
return ListFoldersV1Response{}, errors.NewRequestError(callListFoldersV1Operation, err)
}
if res.IsError() {
return ListFoldersV1Response{}, errors.NewAPIErrorWithResponse(callListFoldersV1Operation, res)
}
return secretsResponse, nil
}

View File

@@ -0,0 +1,57 @@
package api
import (
"github.com/infisical/go-sdk/packages/models"
)
// List folders
type ListFoldersV1Request struct {
ProjectID string `json:"workspaceId"`
Environment string `json:"environment"`
Path string `json:"path,omitempty"`
}
type ListFoldersV1Response struct {
Folders []models.Folder `json:"folders"`
}
// Update folder
type UpdateFolderV1Request struct {
FolderID string `json:"-"`
ProjectID string `json:"workspaceId"`
Environment string `json:"environment"`
NewName string `json:"name"`
Path string `json:"path,omitempty"`
}
type UpdateFolderV1Response struct {
Folder models.Folder `json:"folder"`
}
// Create folder
type CreateFolderV1Request struct {
ProjectID string `json:"workspaceId"`
Environment string `json:"environment"`
Name string `json:"name"`
Path string `json:"path,omitempty"`
}
type CreateFolderV1Response struct {
Folder models.Folder `json:"folder"`
}
// Delete folder
type DeleteFolderV1Request struct {
// Either FolderID or folderName must be provided
FolderID string `json:"-"`
FolderName string `json:"-"`
ProjectID string `json:"workspaceId"`
Environment string `json:"environment"`
Path string `json:"path,omitempty"`
}
type DeleteFolderV1Response struct {
Folder models.Folder `json:"folder"`
}

View File

@@ -0,0 +1,31 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callUpdateFolderV1Operation = "CallUpdateFolderV1"
func CallUpdateFolderV1(httpClient *resty.Client, request UpdateFolderV1Request) (UpdateFolderV1Response, error) {
updateResponse := UpdateFolderV1Response{}
req := httpClient.R().
SetResult(&updateResponse).
SetBody(request)
res, err := req.Patch(fmt.Sprintf("/v1/folders/%s", request.FolderID))
if err != nil {
return UpdateFolderV1Response{}, errors.NewRequestError(callUpdateFolderV1Operation, err)
}
if res.IsError() {
return UpdateFolderV1Response{}, errors.NewAPIErrorWithResponse(callUpdateFolderV1Operation, res)
}
return updateResponse, nil
}

View File

@@ -0,0 +1,27 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callKmsCreateKeyOperationV1 = "CallKmsCreateKeyV1"
func CallKmsCreateKeyV1(httpClient *resty.Client, request KmsCreateKeyV1Request) (KmsCreateKeyV1Response, error) {
kmsCreateKeyResponse := KmsCreateKeyV1Response{}
res, err := httpClient.R().
SetResult(&kmsCreateKeyResponse).
SetBody(request).
Post("/v1/kms/keys")
if err != nil {
return KmsCreateKeyV1Response{}, errors.NewRequestError(callKmsCreateKeyOperationV1, err)
}
if res.IsError() {
return KmsCreateKeyV1Response{}, errors.NewAPIErrorWithResponse(callKmsCreateKeyOperationV1, res)
}
return kmsCreateKeyResponse, nil
}

View File

@@ -0,0 +1,29 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callKmsDecryptDataOperationV1 = "CallKmsDecryptDataV1"
func CallKmsDecryptDataV1(httpClient *resty.Client, request KmsDecryptDataV1Request) (KmsDecryptDataV1Response, error) {
kmsDecryptDataResponse := KmsDecryptDataV1Response{}
res, err := httpClient.R().
SetResult(&kmsDecryptDataResponse).
SetBody(request).
Post(fmt.Sprintf("/v1/kms/keys/%s/decrypt", request.KeyId))
if err != nil {
return KmsDecryptDataV1Response{}, errors.NewRequestError(callKmsDecryptDataOperationV1, err)
}
if res.IsError() {
return KmsDecryptDataV1Response{}, errors.NewAPIErrorWithResponse(callKmsDecryptDataOperationV1, res)
}
return kmsDecryptDataResponse, nil
}

View File

@@ -0,0 +1,29 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callKmsDeleteKeyOperationV1 = "CallKmsDeleteKeyV1"
func CallKmsDeleteKeyV1(httpClient *resty.Client, request KmsDeleteKeyV1Request) (KmsDeleteKeyV1Response, error) {
kmsDeleteKeyResponse := KmsDeleteKeyV1Response{}
res, err := httpClient.R().
SetResult(&kmsDeleteKeyResponse).
SetBody(request).
Delete(fmt.Sprintf("/v1/kms/keys/%s", request.KeyId))
if err != nil {
return KmsDeleteKeyV1Response{}, errors.NewRequestError(callKmsDeleteKeyOperationV1, err)
}
if res.IsError() {
return KmsDeleteKeyV1Response{}, errors.NewAPIErrorWithResponse(callKmsDeleteKeyOperationV1, res)
}
return kmsDeleteKeyResponse, nil
}

View File

@@ -0,0 +1,29 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callKmsEncryptDataOperationV1 = "CallKmsEncryptDataV1"
func CallKmsEncryptDataV1(httpClient *resty.Client, request KmsEncryptDataV1Request) (KmsEncryptDataV1Response, error) {
kmsEncryptDataResponse := KmsEncryptDataV1Response{}
res, err := httpClient.R().
SetResult(&kmsEncryptDataResponse).
SetBody(request).
Post(fmt.Sprintf("/v1/kms/keys/%s/encrypt", request.KeyId))
if err != nil {
return KmsEncryptDataV1Response{}, errors.NewRequestError(callKmsEncryptDataOperationV1, err)
}
if res.IsError() {
return KmsEncryptDataV1Response{}, errors.NewAPIErrorWithResponse(callKmsEncryptDataOperationV1, res)
}
return kmsEncryptDataResponse, nil
}

View File

@@ -0,0 +1,28 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callKmsGetKeyByNameOperationV1 = "CallKmsGetKeyByNameV1"
func CallKmsGetKeyByNameV1(httpClient *resty.Client, request KmsGetKeyByNameV1Request) (KmsGetKeyV1Response, error) {
kmsGetKeyByNameResponse := KmsGetKeyV1Response{}
res, err := httpClient.R().
SetResult(&kmsGetKeyByNameResponse).
Get(fmt.Sprintf("/v1/kms/keys/key-name/%s?projectId=%s", request.KeyName, request.ProjectId))
if err != nil {
return KmsGetKeyV1Response{}, errors.NewRequestError(callKmsGetKeyByNameOperationV1, err)
}
if res.IsError() {
return KmsGetKeyV1Response{}, errors.NewAPIErrorWithResponse(callKmsGetKeyByNameOperationV1, res)
}
return kmsGetKeyByNameResponse, nil
}

View File

@@ -0,0 +1,28 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callKmsGetPublicKeyOperationV1 = "CallKmsGetPublicKeyV1"
func CallKmsGetPublicKeyV1(httpClient *resty.Client, request KmsGetPublicKeyV1Request) (KmsGetPublicKeyV1Response, error) {
kmsGetPublicKeyResponse := KmsGetPublicKeyV1Response{}
res, err := httpClient.R().
SetResult(&kmsGetPublicKeyResponse).
Get(fmt.Sprintf("/v1/kms/keys/%s/public-key", request.KeyId))
if err != nil {
return KmsGetPublicKeyV1Response{}, errors.NewRequestError(callKmsGetPublicKeyOperationV1, err)
}
if res.IsError() {
return KmsGetPublicKeyV1Response{}, errors.NewAPIErrorWithResponse(callKmsGetPublicKeyOperationV1, res)
}
return kmsGetPublicKeyResponse, nil
}

View File

@@ -0,0 +1,29 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callKmsGetSigningAlgorithmsOperationV1 = "CallKmsGetSigningAlgorithmsV1"
func CallKmsGetSigningAlgorithmsV1(httpClient *resty.Client, request KmsListSigningAlgorithmsV1Request) (KmsListSigningAlgorithmsV1Response, error) {
kmsListSigningAlgorithmsResponse := KmsListSigningAlgorithmsV1Response{}
res, err := httpClient.R().
SetResult(&kmsListSigningAlgorithmsResponse).
Get(fmt.Sprintf("/v1/kms/keys/%s/signing-algorithms", request.KeyId))
if err != nil {
return KmsListSigningAlgorithmsV1Response{}, errors.NewRequestError(callKmsGetSigningAlgorithmsOperationV1, err)
}
if res.IsError() {
return KmsListSigningAlgorithmsV1Response{}, errors.NewAPIErrorWithResponse(callKmsGetSigningAlgorithmsOperationV1, res)
}
return kmsListSigningAlgorithmsResponse, nil
}

View File

@@ -0,0 +1,114 @@
package api
type KmsEncryptDataV1Request struct {
KeyId string
Plaintext string `json:"plaintext"`
}
type KmsEncryptDataV1Response struct {
Ciphertext string `json:"ciphertext"`
}
type KmsDecryptDataV1Request struct {
KeyId string
Ciphertext string `json:"ciphertext"`
}
type KmsDecryptDataV1Response struct {
Plaintext string `json:"plaintext"`
}
type KmsSignDataV1Request struct {
KeyId string
Data string `json:"data"`
SigningAlgorithm string `json:"signingAlgorithm"`
IsDigest bool `json:"isDigest"`
}
type KmsSignDataV1Response struct {
Signature string `json:"signature"`
KeyId string `json:"keyId"`
SigningAlgorithm string `json:"signingAlgorithm"`
}
type KmsVerifyDataV1Request struct {
KeyId string
Data string `json:"data"` // Data must be base64 encoded
Signature string `json:"signature"`
SigningAlgorithm string `json:"signingAlgorithm"`
IsDigest bool `json:"isDigest"`
}
type KmsVerifyDataV1Response struct {
SignatureValid bool `json:"signatureValid"`
KeyId string `json:"keyId"`
SigningAlgorithm string `json:"signingAlgorithm"`
}
type KmsListSigningAlgorithmsV1Request struct {
KeyId string
}
type KmsListSigningAlgorithmsV1Response struct {
SigningAlgorithms []string `json:"signingAlgorithms"`
}
type KmsGetPublicKeyV1Request struct {
KeyId string
}
type KmsGetPublicKeyV1Response struct {
PublicKey string `json:"publicKey"`
}
type KmsCreateKeyV1Request struct {
// KeyUsage is the usage of the key. Can be either sign-verify or encrypt-decrypt
KeyUsage string `json:"keyUsage"`
// Description is the description of the key.
Description string `json:"description"`
// Name is the name of the key.
Name string `json:"name"`
// EncryptionAlgorithm is the algorithm that will be used for the key itself.
// `sign-verify algorithms`: `rsa-4096`, `ecc-nist-p256`
// `encrypt-decrypt algorithms`: `aes-256-gcm`, `aes-128-gcm`
EncryptionAlgorithm string `json:"encryptionAlgorithm"`
// ProjectId is the project ID that the key will be created in.
ProjectId string `json:"projectId"`
}
type KmsCreateKeyV1Response struct {
Key KmsKey `json:"key"`
}
type KmsDeleteKeyV1Request struct {
KeyId string
}
type KmsDeleteKeyV1Response struct {
Key KmsKey `json:"key"`
}
type KmsGetKeyByNameV1Request struct {
KeyName string
ProjectId string
}
type KmsGetKeyV1Response struct {
Key KmsKey `json:"key"`
}
type KmsKey struct {
KeyId string `json:"id"`
Description string `json:"description"`
IsDisabled bool `json:"isDisabled"`
OrgId string `json:"orgId"`
Name string `json:"name"`
ProjectId string `json:"projectId"`
KeyUsage string `json:"keyUsage"`
Version int `json:"version"`
EncryptionAlgorithm string `json:"encryptionAlgorithm"`
}

View File

@@ -0,0 +1,29 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callKmsSignDataOperationV1 = "CallKmsSignDataV1"
func CallKmsSignDataV1(httpClient *resty.Client, request KmsSignDataV1Request) (KmsSignDataV1Response, error) {
kmsSignDataResponse := KmsSignDataV1Response{}
res, err := httpClient.R().
SetResult(&kmsSignDataResponse).
SetBody(request).
Post(fmt.Sprintf("/v1/kms/keys/%s/sign", request.KeyId))
if err != nil {
return KmsSignDataV1Response{}, errors.NewRequestError(callKmsSignDataOperationV1, err)
}
if res.IsError() {
return KmsSignDataV1Response{}, errors.NewAPIErrorWithResponse(callKmsSignDataOperationV1, res)
}
return kmsSignDataResponse, nil
}

View File

@@ -0,0 +1,29 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callKmsVerifyDataOperationV1 = "CallKmsVerifyDataV1"
func CallKmsVerifyDataV1(httpClient *resty.Client, request KmsVerifyDataV1Request) (KmsVerifyDataV1Response, error) {
kmsVerifyDataResponse := KmsVerifyDataV1Response{}
res, err := httpClient.R().
SetResult(&kmsVerifyDataResponse).
SetBody(request).
Post(fmt.Sprintf("/v1/kms/keys/%s/verify", request.KeyId))
if err != nil {
return KmsVerifyDataV1Response{}, errors.NewRequestError(callKmsVerifyDataOperationV1, err)
}
if res.IsError() {
return KmsVerifyDataV1Response{}, errors.NewAPIErrorWithResponse(callKmsVerifyDataOperationV1, res)
}
return kmsVerifyDataResponse, nil
}

View File

@@ -0,0 +1,40 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callBatchCreateSecretV3RawOperation = "CallBatchCreateSecretV3Raw"
func CallBatchCreateSecretV3(httpClient *resty.Client, request BatchCreateSecretsV3RawRequest) (BatchCreateSecretsV3RawResponse, error) {
createBatchResponse := BatchCreateSecretsV3RawResponse{}
req := httpClient.R().
SetResult(&createBatchResponse).
SetBody(request)
res, err := req.Post("/v3/secrets/batch/raw")
if err != nil {
return BatchCreateSecretsV3RawResponse{}, errors.NewRequestError(callBatchCreateSecretV3RawOperation, err)
}
if res.IsError() {
return BatchCreateSecretsV3RawResponse{}, errors.NewAPIErrorWithResponse(callBatchCreateSecretV3RawOperation, res)
}
for idx := range createBatchResponse.Secrets {
secretPath := request.SecretPath
if secretPath == "" {
secretPath = "/"
}
createBatchResponse.Secrets[idx].SecretPath = secretPath
}
return createBatchResponse, nil
}

View File

@@ -0,0 +1,31 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callCreateSecretV3RawOperation = "CallCreateSecretV3Raw"
func CallCreateSecretV3(httpClient *resty.Client, request CreateSecretV3RawRequest) (CreateSecretV3RawResponse, error) {
createResponse := CreateSecretV3RawResponse{}
req := httpClient.R().
SetResult(&createResponse).
SetBody(request)
res, err := req.Post(fmt.Sprintf("/v3/secrets/raw/%s", request.SecretKey))
if err != nil {
return CreateSecretV3RawResponse{}, errors.NewRequestError(callCreateSecretV3RawOperation, err)
}
if res.IsError() {
return CreateSecretV3RawResponse{}, errors.NewAPIErrorWithResponse(callCreateSecretV3RawOperation, res)
}
return createResponse, nil
}

View File

@@ -0,0 +1,31 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callDeleteSecretV3RawOperation = "CallDeleteSecretV3Raw"
func CallDeleteSecretV3(httpClient *resty.Client, request DeleteSecretV3RawRequest) (DeleteSecretV3RawResponse, error) {
deleteResponse := DeleteSecretV3RawResponse{}
req := httpClient.R().
SetResult(&deleteResponse).
SetBody(request)
res, err := req.Delete(fmt.Sprintf("/v3/secrets/raw/%s", request.SecretKey))
if err != nil {
return DeleteSecretV3RawResponse{}, errors.NewRequestError(callDeleteSecretV3RawOperation, err)
}
if res.IsError() {
return DeleteSecretV3RawResponse{}, errors.NewAPIErrorWithResponse(callDeleteSecretV3RawOperation, res)
}
return deleteResponse, nil
}

View File

@@ -0,0 +1,75 @@
package api
import (
"encoding/json"
"fmt"
"github.com/go-resty/resty/v2"
"github.com/hashicorp/golang-lru/v2/expirable"
"github.com/infisical/go-sdk/packages/errors"
"github.com/infisical/go-sdk/packages/util"
)
const callListSecretsV3RawOperation = "CallListSecretsV3Raw"
func CallListSecretsV3(cache *expirable.LRU[string, interface{}], httpClient *resty.Client, request ListSecretsV3RawRequest) (ListSecretsV3RawResponse, error) {
var cacheKey string
if cache != nil {
reqBytes, err := json.Marshal(request)
if err != nil {
return ListSecretsV3RawResponse{}, err
}
cacheKey = util.ComputeCacheKeyFromBytes(reqBytes, callListSecretsV3RawOperation)
if cached, found := cache.Get(cacheKey); found {
if response, ok := cached.(ListSecretsV3RawResponse); ok {
return response, nil
}
cache.Remove(cacheKey)
}
}
secretsResponse := ListSecretsV3RawResponse{}
if request.SecretPath == "" {
request.SecretPath = "/"
}
req := httpClient.R().
SetResult(&secretsResponse).
SetQueryParams(map[string]string{
"workspaceId": request.ProjectID,
"workspaceSlug": request.ProjectSlug,
"environment": request.Environment,
"secretPath": request.SecretPath,
"expandSecretReferences": fmt.Sprintf("%t", request.ExpandSecretReferences),
"include_imports": fmt.Sprintf("%t", request.IncludeImports),
"recursive": fmt.Sprintf("%t", request.Recursive),
})
if request.IfNoneMatch != "" {
req.SetHeader("If-None-Match", request.IfNoneMatch)
}
res, err := req.Get("/v3/secrets/raw")
if err != nil {
return ListSecretsV3RawResponse{}, errors.NewRequestError(callListSecretsV3RawOperation, err)
}
if res.StatusCode() == 304 {
return ListSecretsV3RawResponse{}, errors.NewNotModifiedError(callListSecretsV3RawOperation)
}
if res.IsError() {
return ListSecretsV3RawResponse{}, errors.NewAPIErrorWithResponse(callListSecretsV3RawOperation, res)
}
secretsResponse.ETag = res.Header().Get("ETag")
if cache != nil {
cache.Add(cacheKey, secretsResponse)
}
return secretsResponse, nil
}

View File

@@ -0,0 +1,113 @@
package api
import "github.com/infisical/go-sdk/packages/models"
// List secrets
type ListSecretsV3RawRequest struct {
AttachToProcessEnv bool `json:"-"`
// ProjectId and ProjectSlug are used to fetch secrets from the project. Only one of them is required.
ProjectID string `json:"workspaceId,omitempty"`
ProjectSlug string `json:"workspaceSlug,omitempty"`
Environment string `json:"environment"`
ExpandSecretReferences bool `json:"expandSecretReferences"`
IncludeImports bool `json:"include_imports"`
Recursive bool `json:"recursive"`
SecretPath string `json:"secretPath,omitempty"`
SkipUniqueValidation bool `json:"skip_unique_validation,omitempty"`
IfNoneMatch string `json:"-"`
}
type ListSecretsV3RawResponse struct {
Secrets []models.Secret `json:"secrets"`
Imports []models.SecretImport `json:"imports"`
ETag string `json:"etag"`
}
// Retrieve secret
type RetrieveSecretV3RawRequest struct {
SecretKey string `json:"secretKey"`
ProjectSlug string `json:"workspaceSlug,omitempty"`
ProjectID string `json:"workspaceId,omitempty"`
Environment string `json:"environment"`
SecretPath string `json:"secretPath,omitempty"`
Type string `json:"type,omitempty"`
IncludeImports bool `json:"include_imports"`
ExpandSecretReferences bool `json:"expandSecretReferences"`
Version int `json:"version,omitempty"`
}
type RetrieveSecretV3RawResponse struct {
Secret models.Secret `json:"secret"`
}
// Update secret
type UpdateSecretV3RawRequest struct {
SecretKey string `json:"-"`
ProjectID string `json:"workspaceId"`
Environment string `json:"environment"`
SecretPath string `json:"secretPath,omitempty"`
Type string `json:"type,omitempty"`
NewSecretValue string `json:"secretValue,omitempty"`
NewSkipMultilineEncoding bool `json:"skipMultilineEncoding,omitempty"`
}
type UpdateSecretV3RawResponse struct {
Secret models.Secret `json:"secret"`
}
// Create secret
type CreateSecretV3RawRequest struct {
SecretKey string `json:"-"`
ProjectID string `json:"workspaceId"`
Environment string `json:"environment"`
SecretPath string `json:"secretPath,omitempty"`
Type string `json:"type,omitempty"`
SecretComment string `json:"secretComment,omitempty"`
SkipMultiLineEncoding bool `json:"skipMultilineEncoding"`
SecretValue string `json:"secretValue"`
}
type CreateSecretV3RawResponse struct {
Secret models.Secret `json:"secret"`
}
// Delete secret
type DeleteSecretV3RawRequest struct {
SecretKey string `json:"-"`
ProjectID string `json:"workspaceId"`
Environment string `json:"environment"`
SecretPath string `json:"secretPath,omitempty"`
Type string `json:"type,omitempty"`
}
type DeleteSecretV3RawResponse struct {
Secret models.Secret `json:"secret"`
}
type BatchCreateSecret struct {
SecretKey string `json:"secretKey"`
SecretValue string `json:"secretValue"`
SecretComment string `json:"secretComment,omitempty"`
SkipMultiLineEncoding bool `json:"skipMultilineEncoding,omitempty"`
SecretMetadata []models.SecretMetadata `json:"secretMetadata,omitempty"`
TagIDs []string `json:"tagIds,omitempty"`
}
type BatchCreateSecretsV3RawRequest struct {
Environment string `json:"environment"`
ProjectID string `json:"workspaceId"`
SecretPath string `json:"secretPath,omitempty"`
Secrets []BatchCreateSecret `json:"secrets"`
}
type BatchCreateSecretsV3RawResponse struct {
Secrets []models.Secret `json:"secrets"`
}

View File

@@ -0,0 +1,81 @@
package api
import (
"encoding/json"
"errors"
"fmt"
"github.com/go-resty/resty/v2"
"github.com/hashicorp/golang-lru/v2/expirable"
sdkErrors "github.com/infisical/go-sdk/packages/errors"
"github.com/infisical/go-sdk/packages/util"
)
const callRetrieveSecretV3RawOperation = "CallRetrieveSecretV3Raw"
func CallRetrieveSecretV3(cache *expirable.LRU[string, interface{}], httpClient *resty.Client, request RetrieveSecretV3RawRequest) (RetrieveSecretV3RawResponse, error) {
var cacheKey string
if cache != nil {
reqBytes, err := json.Marshal(request)
if err != nil {
return RetrieveSecretV3RawResponse{}, err
}
cacheKey = util.ComputeCacheKeyFromBytes(reqBytes, callRetrieveSecretV3RawOperation)
if cached, found := cache.Get(cacheKey); found {
if response, ok := cached.(RetrieveSecretV3RawResponse); ok {
return response, nil
}
cache.Remove(cacheKey)
}
}
retrieveResponse := RetrieveSecretV3RawResponse{}
if request.Type == "" {
request.Type = "shared"
}
if request.SecretPath == "" {
request.SecretPath = "/"
}
queryParams := map[string]string{
"environment": request.Environment,
"secretPath": request.SecretPath,
"expandSecretReferences": fmt.Sprintf("%t", request.ExpandSecretReferences),
"include_imports": fmt.Sprintf("%t", request.IncludeImports),
"type": request.Type,
}
if request.ProjectID != "" {
queryParams["workspaceId"] = request.ProjectID
} else if request.ProjectSlug != "" {
queryParams["workspaceSlug"] = request.ProjectSlug
} else {
return RetrieveSecretV3RawResponse{}, errors.New("projectId or projectSlug is required")
}
if request.Version != 0 {
queryParams["version"] = fmt.Sprintf("%d", request.Version)
}
req := httpClient.R().
SetResult(&retrieveResponse).
SetQueryParams(queryParams)
res, err := req.Get(fmt.Sprintf("/v3/secrets/raw/%s", request.SecretKey))
if err != nil {
return RetrieveSecretV3RawResponse{}, sdkErrors.NewRequestError(callRetrieveSecretV3RawOperation, err)
}
if res.IsError() {
return RetrieveSecretV3RawResponse{}, sdkErrors.NewAPIErrorWithResponse(callRetrieveSecretV3RawOperation, res)
}
if cache != nil {
cache.Add(cacheKey, retrieveResponse)
}
return retrieveResponse, nil
}

View File

@@ -0,0 +1,31 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callUpdateSecretV3RawOperation = "CallUpdateSecretV3Raw"
func CallUpdateSecretV3(httpClient *resty.Client, request UpdateSecretV3RawRequest) (UpdateSecretV3RawResponse, error) {
updateResponse := UpdateSecretV3RawResponse{}
req := httpClient.R().
SetResult(&updateResponse).
SetBody(request)
res, err := req.Patch(fmt.Sprintf("/v3/secrets/raw/%s", request.SecretKey))
if err != nil {
return UpdateSecretV3RawResponse{}, errors.NewRequestError(callUpdateSecretV3RawOperation, err)
}
if res.IsError() {
return UpdateSecretV3RawResponse{}, errors.NewAPIErrorWithResponse(callUpdateSecretV3RawOperation, res)
}
return updateResponse, nil
}

View File

@@ -0,0 +1,27 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callAddSshHostOperation = "CallAddSshHostV1"
func CallAddSshHostV1(httpClient *resty.Client, body AddSshHostV1Request) (AddSshHostV1Response, error) {
resp := AddSshHostV1Response{}
res, err := httpClient.R().
SetBody(body).
SetResult(&resp).
Post("/v1/ssh/hosts")
if err != nil {
return AddSshHostV1Response{}, errors.NewRequestError(callAddSshHostOperation, err)
}
if res.IsError() {
return AddSshHostV1Response{}, errors.NewAPIErrorWithResponse(callAddSshHostOperation, res)
}
return resp, nil
}

View File

@@ -0,0 +1,21 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
func GetSshHostHostCaPublicKeyV1(httpClient *resty.Client, sshHostId string) (string, error) {
res, err := httpClient.R().
Get("/v1/ssh/hosts/" + sshHostId + "/host-ca-public-key")
if err != nil {
return "", errors.NewRequestError("GetSshHostHostCaPublicKeyV1", err)
}
if res.IsError() {
return "", errors.NewAPIErrorWithResponse("GetSshHostHostCaPublicKeyV1", res)
}
return res.String(), nil
}

View File

@@ -0,0 +1,21 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
func GetSshHostUserCaPublicKeyV1(httpClient *resty.Client, sshHostId string) (string, error) {
res, err := httpClient.R().
Get("/v1/ssh/hosts/" + sshHostId + "/user-ca-public-key")
if err != nil {
return "", errors.NewRequestError("GetSshHostUserCaPublicKeyV1", err)
}
if res.IsError() {
return "", errors.NewAPIErrorWithResponse("GetSshHostUserCaPublicKeyV1", res)
}
return res.String(), nil
}

View File

@@ -0,0 +1,26 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callGetSshHostsOperation = "CallGetSshHostsV1"
func GetSshHostsV1(httpClient *resty.Client, _ GetSshHostsV1Request) (GetSshHostsV1Response, error) {
var getSshHostsResponse GetSshHostsV1Response
res, err := httpClient.R().
SetResult(&getSshHostsResponse).
Get("/v1/ssh/hosts")
if err != nil {
return nil, errors.NewRequestError(callGetSshHostsOperation, err)
}
if res.IsError() {
return nil, errors.NewAPIErrorWithResponse(callGetSshHostsOperation, res)
}
return getSshHostsResponse, nil
}

View File

@@ -0,0 +1,27 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callIssueSshCredsOperation = "CallIssueSshCredsV1"
func CallIssueSshCredsV1(httpClient *resty.Client, request IssueSshCredsV1Request) (IssueSshCredsV1Response, error) {
issueSshCredsResponse := IssueSshCredsV1Response{}
res, err := httpClient.R().
SetResult(&issueSshCredsResponse).
SetBody(request).
Post("/v1/ssh/certificates/issue")
if err != nil {
return IssueSshCredsV1Response{}, errors.NewRequestError(callIssueSshCredsOperation, err)
}
if res.IsError() {
return IssueSshCredsV1Response{}, errors.NewAPIErrorWithResponse(callIssueSshCredsOperation, res)
}
return issueSshCredsResponse, nil
}

View File

@@ -0,0 +1,29 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callIssueSshHostHostCertOperation = "CallIssueSshHostHostCertV1"
func CallIssueSshHostHostCertV1(httpClient *resty.Client, sshHostId string, body IssueSshHostHostCertV1Request) (IssueSshHostHostCertV1Response, error) {
resp := IssueSshHostHostCertV1Response{}
res, err := httpClient.R().
SetBody(body).
SetResult(&resp).
Post(fmt.Sprintf("/v1/ssh/hosts/%s/issue-host-cert", sshHostId))
if err != nil {
return IssueSshHostHostCertV1Response{}, errors.NewRequestError(callIssueSshHostHostCertOperation, err)
}
if res.IsError() {
return IssueSshHostHostCertV1Response{}, errors.NewAPIErrorWithResponse(callIssueSshHostHostCertOperation, res)
}
return resp, nil
}

View File

@@ -0,0 +1,29 @@
package api
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callIssueSshHostUserCertOperation = "CallIssueSshHostUserCertV1"
func CallIssueSshHostUserCertV1(httpClient *resty.Client, sshHostId string, body IssueSshHostUserCertV1Request) (IssueSshHostUserCertV1Response, error) {
resp := IssueSshHostUserCertV1Response{}
res, err := httpClient.R().
SetBody(body).
SetResult(&resp).
Post(fmt.Sprintf("/v1/ssh/hosts/%s/issue-user-cert", sshHostId))
if err != nil {
return IssueSshHostUserCertV1Response{}, errors.NewRequestError(callIssueSshHostUserCertOperation, err)
}
if res.IsError() {
return IssueSshHostUserCertV1Response{}, errors.NewAPIErrorWithResponse(callIssueSshHostUserCertOperation, res)
}
return resp, nil
}

View File

@@ -0,0 +1,95 @@
package api
import (
"github.com/infisical/go-sdk/packages/util"
)
type SignSshPublicKeyV1Request struct {
CertificateTemplateID string `json:"certificateTemplateId"`
PublicKey string `json:"publicKey"`
CertType util.SshCertType `json:"certType,omitempty"`
Principals []string `json:"principals"`
TTL string `json:"ttl,omitempty"`
KeyID string `json:"keyId,omitempty"`
}
type SignSshPublicKeyV1Response struct {
SerialNumber string `json:"serialNumber"`
SignedKey string `json:"signedKey"`
}
type IssueSshCredsV1Request struct {
CertificateTemplateID string `json:"certificateTemplateId"`
KeyAlgorithm util.CertKeyAlgorithm `json:"keyAlgorithm,omitempty"`
CertType util.SshCertType `json:"certType,omitempty"`
Principals []string `json:"principals"`
TTL string `json:"ttl,omitempty"`
KeyID string `json:"keyId,omitempty"`
}
type IssueSshCredsV1Response struct {
SerialNumber string `json:"serialNumber"`
SignedKey string `json:"signedKey"`
PrivateKey string `json:"privateKey"`
PublicKey string `json:"publicKey"`
KeyAlgorithm util.CertKeyAlgorithm `json:"keyAlgorithm"`
}
type GetSshHostsV1Request struct{}
type AllowedPrincipals struct {
Usernames []string `json:"usernames"`
}
type SshHostLoginMapping struct {
LoginUser string `json:"loginUser"`
AllowedPrincipals AllowedPrincipals `json:"allowedPrincipals"`
}
type SshHost struct {
ID string `json:"id"`
ProjectID string `json:"projectId"`
Hostname string `json:"hostname"`
Alias string `json:"alias,omitempty"`
UserCertTtl string `json:"userCertTtl"`
HostCertTtl string `json:"hostCertTtl"`
UserSshCaId string `json:"userSshCaId"`
HostSshCaId string `json:"hostSshCaId"`
LoginMappings []SshHostLoginMapping `json:"loginMappings"`
}
type GetSshHostsV1Response []SshHost
type IssueSshHostUserCertV1Request struct {
LoginUser string `json:"loginUser"`
}
type IssueSshHostUserCertV1Response struct {
SerialNumber string `json:"serialNumber"`
SignedKey string `json:"signedKey"`
PrivateKey string `json:"privateKey"`
PublicKey string `json:"publicKey"`
KeyAlgorithm util.CertKeyAlgorithm `json:"keyAlgorithm"`
}
type IssueSshHostHostCertV1Request struct {
PublicKey string `json:"publicKey"`
}
type IssueSshHostHostCertV1Response struct {
SerialNumber string `json:"serialNumber"`
SignedKey string `json:"signedKey"`
}
type AddSshHostV1Request struct {
ProjectID string `json:"projectId"`
Hostname string `json:"hostname"`
Alias string `json:"alias,omitempty"`
UserCertTtl string `json:"userCertTtl,omitempty"`
HostCertTtl string `json:"hostCertTtl,omitempty"`
UserSshCaId string `json:"userSshCaId,omitempty"`
HostSshCaId string `json:"hostSshCaId,omitempty"`
LoginMappings []SshHostLoginMapping `json:"loginMappings,omitempty"`
}
type AddSshHostV1Response SshHost

View File

@@ -0,0 +1,27 @@
package api
import (
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/errors"
)
const callSignSshPublicKeyOperation = "CallSignSshPublicKeyV1"
func CallSignSshPublicKeyV1(httpClient *resty.Client, request SignSshPublicKeyV1Request) (SignSshPublicKeyV1Response, error) {
signSshPublicKeyResponse := SignSshPublicKeyV1Response{}
res, err := httpClient.R().
SetResult(&signSshPublicKeyResponse).
SetBody(request).
Post("/v1/ssh/certificates/sign")
if err != nil {
return SignSshPublicKeyV1Response{}, errors.NewRequestError(callSignSshPublicKeyOperation, err)
}
if res.IsError() {
return SignSshPublicKeyV1Response{}, errors.NewAPIErrorWithResponse(callSignSshPublicKeyOperation, res)
}
return signSshPublicKeyResponse, nil
}

View File

@@ -0,0 +1,75 @@
package errors
import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/util"
)
// APIError represents an error response from the API
type APIError struct {
Operation string `json:"operation"`
Method string `json:"method"`
URL string `json:"url"`
StatusCode int `json:"statusCode"`
ErrorMessage string `json:"message,omitempty"`
ReqId string `json:"reqId,omitempty"`
}
func (e *APIError) Error() string {
msg := fmt.Sprintf(
"APIError: %s unsuccessful response [%v %v] [status-code=%v] [reqId=%v]",
e.Operation,
e.Method,
e.URL,
e.StatusCode,
e.ReqId,
)
if e.ErrorMessage != "" {
return fmt.Sprintf("%s [message=\"%s\"]", msg, e.ErrorMessage)
}
return msg
}
func NewAPIError(operation string, res *resty.Response) error {
return &APIError{
Operation: operation,
Method: res.Request.Method,
URL: res.Request.URL,
StatusCode: res.StatusCode(),
}
}
func NewAPIErrorWithResponse(operation string, res *resty.Response) error {
errorMessage := util.TryParseErrorBody(res)
reqId := util.TryExtractReqId(res)
return &APIError{
Operation: operation,
Method: res.Request.Method,
URL: res.Request.URL,
StatusCode: res.StatusCode(),
ErrorMessage: errorMessage,
ReqId: reqId,
}
}
// NotModifiedError is returned when the server responds with 304 Not Modified,
// indicating the resource has not changed since the last request (based on ETag).
type NotModifiedError struct {
Operation string
}
func (e *NotModifiedError) Error() string {
return fmt.Sprintf("%s: secrets not modified (HTTP 304)", e.Operation)
}
func NewNotModifiedError(operation string) error {
return &NotModifiedError{
Operation: operation,
}
}

View File

@@ -0,0 +1,22 @@
package errors
import (
"fmt"
)
// RequestError represents an error that occurred during an API request
type RequestError struct {
Operation string `json:"operation"`
error error `json:"-"`
}
func (e *RequestError) Error() string {
return fmt.Sprintf("%s: unable to complete api request [err=%s]", e.Operation, e.error)
}
func NewRequestError(operation string, err error) error {
return &RequestError{
Operation: operation,
error: err,
}
}

View File

@@ -0,0 +1,66 @@
package models
type TokenType string
const (
BEARER_TOKEN_TYPE TokenType = "Bearer"
)
type UniversalAuthCredential struct {
ClientID string
ClientSecret string
}
type AccessTokenCredential struct {
AccessToken string
}
type GCPIDTokenCredential struct {
IdentityID string
}
type GCPIAMCredential struct {
IdentityID string
ServiceAccountKeyFilePath string
}
type AWSIAMCredential struct {
IdentityID string
}
type KubernetesCredential struct {
IdentityID string
ServiceAccountToken string
}
type AzureCredential struct {
IdentityID string
Resource string
ClientID string
}
type OIDCCredential struct {
IdentityID string
JWT string
}
type JWTCredential struct {
IdentityID string
JWT string
}
type LDAPCredential struct {
IdentityID string
Username string
Password string
}
type OCICredential struct {
IdentityID string
PrivateKey string
Fingerprint string
UserID string
TenancyID string
Region string
Passphrase *string
}

View File

@@ -0,0 +1,44 @@
package models
import "time"
type DynamicSecret struct {
Id string `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Version int `json:"number"`
DefaultTTL string `json:"defaultTTL"`
MaxTTL string `json:"maxTTL"`
FolderID string `json:"folderId"`
Status string `json:"status"`
StatusDetails string `json:"statusDetails"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
type DynamicSecretLease struct {
Id string `json:"id"`
Type string `json:"type"`
Version int `json:"number"`
ExternalEntityId string `json:"externalEntityId"`
ExpireAt time.Time `json:"expireAt"`
Status string `json:"status"`
DynamicSecretId string `json:"dynamicSecretId"`
StatusDetails string `json:"statusDetails"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
type DynamicSecretLeaseWithDynamicSecret struct {
Id string `json:"id"`
Type string `json:"type"`
Version int `json:"number"`
ExternalEntityId string `json:"externalEntityId"`
ExpireAt time.Time `json:"expireAt"`
Status string `json:"status"`
DynamicSecretId string `json:"dynamicSecretId"`
StatusDetails string `json:"statusDetails"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DynamicSecret DynamicSecret `json:"dynamicSecret"`
}

View File

@@ -0,0 +1,14 @@
package models
import "time"
type Folder struct {
ID string `json:"id"`
Name string `json:"name"`
Version int `json:"version"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
EnvironmentID string `json:"envId"`
ParentID string `json:"parentId"`
IsReserved bool `json:"isReserved"`
}

View File

@@ -0,0 +1,34 @@
package models
type SecretMetadata struct {
Key string `json:"key"`
Value string `json:"value"`
}
type SecretTag struct {
ID string `json:"id"`
Slug string `json:"slug"`
Name string `json:"name"`
Color string `json:"color"`
}
type Secret struct {
ID string `json:"id"`
Workspace string `json:"workspace"`
Environment string `json:"environment"`
Version int `json:"version"`
Type string `json:"type"`
SecretKey string `json:"secretKey"`
SecretValue string `json:"secretValue"`
SecretComment string `json:"secretComment"`
SecretPath string `json:"secretPath,omitempty"`
SecretMetadata []SecretMetadata `json:"secretMetadata"`
Tags []SecretTag `json:"tags"`
}
type SecretImport struct {
SecretPath string `json:"secretPath"`
Environment string `json:"environment"`
FolderID string `json:"folderId"`
Secrets []Secret `json:"secrets"`
}

View File

@@ -0,0 +1,244 @@
package util
import (
"context"
"encoding/json"
"fmt"
"net/url"
"os"
"time"
credentials "cloud.google.com/go/iam/credentials/apiv1"
"cloud.google.com/go/iam/credentials/apiv1/credentialspb"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/go-resty/resty/v2"
"google.golang.org/api/option"
)
func GetKubernetesServiceAccountToken(serviceAccountTokenPath string) (string, error) {
if serviceAccountTokenPath == "" {
serviceAccountTokenPath = DEFAULT_KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH
}
token, err := os.ReadFile(serviceAccountTokenPath)
if err != nil {
return "", err
}
return string(token), nil
}
func buildAzureMetadataServiceURL(resource string, clientID string) string {
azureURL := AZURE_METADATA_SERVICE_URL + AZURE_DEFAULT_RESOURCE
if resource != "" {
azureURL = AZURE_METADATA_SERVICE_URL + url.QueryEscape(resource)
}
if clientID != "" {
azureURL += "&client_id=" + url.QueryEscape(clientID)
}
return azureURL
}
// GetAzureMetadataToken fetches a JWT from the Azure IMDS endpoint.
// The optional clientID parameter targets a specific User-Assigned Managed Identity;
// pass "" for System-Assigned Managed Identity.
func GetAzureMetadataToken(httpClient *resty.Client, customResource string, clientID string) (string, error) {
type AzureMetadataResponse struct {
AccessToken string `json:"access_token"`
}
metadataResponse := AzureMetadataResponse{}
response, err := httpClient.R().
SetResult(&metadataResponse).
SetHeader("Metadata", "true").
SetHeader("Accept", "application/json").
Get(buildAzureMetadataServiceURL(customResource, clientID))
if err != nil {
return "", err
}
if response.IsError() {
return "", fmt.Errorf("GetAzureMetadataToken: Unsuccessful response [%v %v] [status-code=%v] [Error: %s]", response.Request.Method, response.Request.URL, response.StatusCode(), TryParseErrorBody(response))
}
return metadataResponse.AccessToken, nil
}
func GetGCPMetadataToken(httpClient *resty.Client, identityID string) (string, error) {
res, err := httpClient.R().
SetHeader("Metadata-Flavor", "Google").
Get(fmt.Sprintf("http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=%s&format=full", identityID))
if err != nil {
return "", err
}
if res.IsError() {
return "", fmt.Errorf("GetGCPMetadataToken: Unsuccessful response [%v %v] [status-code=%v] [Error: %s]", res.Request.Method, res.Request.URL, res.StatusCode(), TryParseErrorBody(res))
}
return res.String(), nil
}
func GetAwsEC2IdentityDocumentRegion(timeout int) (string, error) {
type AwsIdentityDocument struct {
Region string `json:"region"`
}
httpClient := resty.New().SetTimeout(time.Duration(timeout) * time.Millisecond)
res, err := httpClient.R().
SetHeader("X-aws-ec2-metadata-token-ttl-seconds", "21600").
Put(AWS_EC2_METADATA_TOKEN_URL)
if err != nil {
return "", err
}
if res.IsError() {
return "", fmt.Errorf("GetAwsEC2IdentityDocumentRegion: Unsuccessful response [%v %v] [status-code=%v] [Error: %s]", res.Request.Method, res.Request.URL, res.StatusCode(), TryParseErrorBody(res))
}
metadataToken := res.String()
res, err = httpClient.R().
SetHeader("X-aws-ec2-metadata-token", metadataToken).
SetHeader("Accept", "application/json").
Get(AWS_EC2_INSTANCE_IDENTITY_DOCUMENT_URL)
if err != nil {
return "", err
}
if res.IsError() {
return "", fmt.Errorf("GetAwsEC2IdentityDocumentRegion: Unsuccessful response [%v %v] [status-code=%v] [Error: %s]", res.Request.Method, res.Request.URL, res.StatusCode(), TryParseErrorBody(res))
}
// For some reason using .SetResult(&AwsIdentityDocument{}) doesn't work and just results in an empty object. This works though..
var identityDocument AwsIdentityDocument
err = json.Unmarshal(res.Body(), &identityDocument)
if err != nil {
return "", err
}
return identityDocument.Region, nil
}
func GetGCPIamServiceAccountToken(identityID string, serviceAccountKeyPath string) (string, error) {
type JwtPayload struct {
Sub string `json:"sub"`
Aud string `json:"aud"`
}
ctx := context.Background()
serviceAccountKey, err := os.ReadFile(serviceAccountKeyPath)
if err != nil {
return "", err
}
var creds map[string]string
if err := json.Unmarshal(serviceAccountKey, &creds); err != nil {
return "", fmt.Errorf("failed to unmarshal service account key: %v", err)
}
clientEmail := creds["client_email"]
if clientEmail == "" {
return "", fmt.Errorf("client email not found in service account key")
}
payload := JwtPayload{
Sub: clientEmail,
Aud: identityID,
}
payloadJSON, err := json.Marshal(payload)
if err != nil {
return "", fmt.Errorf("failed to marshal JWT payload: %v", err)
}
iamCredentialsClient, err := credentials.NewIamCredentialsClient(ctx, option.WithCredentialsFile(serviceAccountKeyPath)) //nolint:staticcheck // deprecated but no drop-in replacement available yet
if err != nil {
return "", fmt.Errorf("failed to create IAM credentials client: %v", err)
}
defer iamCredentialsClient.Close() //nolint:errcheck
signJwtRequest := &credentialspb.SignJwtRequest{
Name: fmt.Sprintf("projects/-/serviceAccounts/%s", clientEmail),
Payload: string(payloadJSON),
}
resp, err := iamCredentialsClient.SignJwt(ctx, signJwtRequest)
if err != nil {
return "", fmt.Errorf("failed to sign JWT: %v. Ensure the IAM Service Account Credentials API is enabled", err)
}
signedJwt := resp.SignedJwt
if signedJwt == "" {
return "", fmt.Errorf("failed to sign JWT: signedJwt is empty")
}
return signedJwt, nil
}
func GetAwsRegion() (string, error) {
// in Lambda environments, the region is available in the AWS_REGION environment variable
region := os.Getenv("AWS_REGION")
if region != "" {
return region, nil
}
// in EC2 environments, the region is available in the identity doc
region, err := GetAwsEC2IdentityDocumentRegion(5000)
if err != nil {
return "", err
}
return region, nil
}
func RetrieveAwsCredentials() (credentials aws.Credentials, region string, err error) {
presetAwsCfg, err := config.LoadDefaultConfig(context.TODO())
if err == nil && presetAwsCfg.Region != "" {
creds, err := presetAwsCfg.Credentials.Retrieve(context.TODO())
if err == nil {
return creds, presetAwsCfg.Region, nil
}
}
awsRegion, err := GetAwsRegion()
if err != nil {
return aws.Credentials{}, "", err
}
awsCfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(awsRegion))
if err != nil {
return aws.Credentials{}, "", fmt.Errorf("unable to load SDK config, %v", err)
}
creds, err := awsCfg.Credentials.Retrieve(context.TODO())
if err != nil {
return aws.Credentials{}, "", fmt.Errorf("error retrieving credentials: %v", err)
}
return creds, awsRegion, nil
}

View File

@@ -0,0 +1,92 @@
package util
import (
"context"
"errors"
)
// Auth related:
const (
INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME = "INFISICAL_AUTH_ORGANIZATION_SLUG"
// Universal auth:
INFISICAL_UNIVERSAL_AUTH_CLIENT_ID_ENV_NAME = "INFISICAL_UNIVERSAL_AUTH_CLIENT_ID"
INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET_ENV_NAME = "INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET"
// GCP auth:
INFISICAL_GCP_AUTH_IDENTITY_ID_ENV_NAME = "INFISICAL_GCP_AUTH_IDENTITY_ID"
INFISICAL_GCP_IAM_SERVICE_ACCOUNT_KEY_FILE_PATH_ENV_NAME = "INFISICAL_GCP_IAM_SERVICE_ACCOUNT_KEY_FILE_PATH"
// AWS auth:
INFISICAL_AWS_IAM_AUTH_IDENTITY_ID_ENV_NAME = "INFISICAL_AWS_IAM_AUTH_IDENTITY_ID"
// Azure auth:
INFISICAL_AZURE_AUTH_IDENTITY_ID_ENV_NAME = "INFISICAL_AZURE_AUTH_IDENTITY_ID"
INFISICAL_AZURE_AUTH_CLIENT_ID_ENV_NAME = "INFISICAL_AZURE_AUTH_CLIENT_ID"
// OCI auth:
INFISICAL_OCI_AUTH_IDENTITY_ID_ENV_NAME = "INFISICAL_OCI_AUTH_IDENTITY_ID"
// LDAP auth:
INFISICAL_LDAP_AUTH_IDENTITY_ID_ENV_NAME = "INFISICAL_LDAP_AUTH_IDENTITY_ID"
// Kubernetes auth:
INFISICAL_KUBERNETES_IDENTITY_ID_ENV_NAME = "INFISICAL_KUBERNETES_IDENTITY_ID"
INFISICAL_KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH_ENV_NAME = "INFISICAL_KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH"
// OIDC auth:
INFISICAL_OIDC_AUTH_IDENTITY_ID_ENV_NAME = "INFISICAL_OIDC_AUTH_IDENTITY_ID"
// Access token:
INFISICAL_ACCESS_TOKEN_ENV_NAME = "INFISICAL_ACCESS_TOKEN"
// AWS metadata service:
AWS_EC2_METADATA_TOKEN_URL = "http://169.254.169.254/latest/api/token"
AWS_EC2_INSTANCE_IDENTITY_DOCUMENT_URL = "http://169.254.169.254/latest/dynamic/instance-identity/document"
// Azure metadata service:
AZURE_METADATA_SERVICE_URL = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=" // End of the URL needs to be appended with the resource
AZURE_DEFAULT_RESOURCE = "https%3A%2F%2Fmanagement.azure.com/"
)
type AuthMethod string
const (
ACCESS_TOKEN AuthMethod = "ACCESS_TOKEN"
UNIVERSAL_AUTH AuthMethod = "UNIVERSAL_AUTH"
GCP_ID_TOKEN AuthMethod = "GCP_ID_TOKEN"
GCP_IAM AuthMethod = "GCP_IAM"
AWS_IAM AuthMethod = "AWS_IAM"
KUBERNETES AuthMethod = "KUBERNETES"
AZURE AuthMethod = "AZURE"
OIDC_AUTH AuthMethod = "OIDC_AUTH"
JWT_AUTH AuthMethod = "JWT_AUTH"
LDAP_AUTH AuthMethod = "LDAP_AUTH"
OCI_AUTH AuthMethod = "OCI_AUTH"
)
// SSH related:
type CertKeyAlgorithm string
const (
RSA2048 CertKeyAlgorithm = "RSA_2048"
RSA4096 CertKeyAlgorithm = "RSA_4096"
ECDSAP256 CertKeyAlgorithm = "EC_prime256v1"
ECDSAP384 CertKeyAlgorithm = "EC_secp384r1"
)
type SshCertType string
const (
UserCert SshCertType = "user"
HostCert SshCertType = "host"
)
// General:
const (
DEFAULT_INFISICAL_API_URL = "https://app.infisical.com/api"
DEFAULT_KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/token"
)
var ErrContextCanceled = errors.New("context canceled")
var ErrContextDeadlineExceeded error = context.DeadlineExceeded

View File

@@ -0,0 +1,146 @@
package util
import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"sort"
"strings"
"time"
"github.com/go-resty/resty/v2"
"github.com/infisical/go-sdk/packages/models"
"github.com/rs/zerolog"
)
func AppendAPIEndpoint(siteUrl string) string {
// Ensure the address does not already end with "/api"
if strings.HasSuffix(siteUrl, "/api") {
return siteUrl
}
// Check if the address ends with a slash and append accordingly
if siteUrl[len(siteUrl)-1] == '/' {
return siteUrl + "api"
}
return siteUrl + "/api"
}
func PrintWarning(logger zerolog.Logger, message string) {
logger.Warn().Msgf("[Infisical] Warning: %v", message)
}
func EnsureUniqueSecretsByKey(secrets *[]models.Secret, skipUniqueKey bool) {
secretMap := make(map[string]models.Secret)
// Move secrets to a map to ensure uniqueness
for _, secret := range *secrets {
var key string
if skipUniqueKey {
// Create a composite key using both SecretPath and SecretKey
key = secret.SecretPath + ":" + secret.SecretKey
} else {
// Use only SecretKey for global uniqueness
key = secret.SecretKey
}
secretMap[key] = secret
}
// Clear the slice
*secrets = (*secrets)[:0]
// Refill the slice from the map
for _, secret := range secretMap {
*secrets = append(*secrets, secret)
}
}
// containsSecret checks if the given key exists in the slice of secrets
func ContainsSecret(secrets []models.Secret, key string) bool {
for _, secret := range secrets {
if secret.SecretKey == key {
return true
}
}
return false
}
// Helper function to sort the secrets by key so we can create a consistent output
func SortSecretsByKeys(secrets []models.Secret) []models.Secret {
sort.Slice(secrets, func(i, j int) bool {
return secrets[i].SecretKey < secrets[j].SecretKey
})
return secrets
}
/*
If the status code is 400, there will most likely always be a body.
The body is a json object with a message key. we need to try to parse it, but if it fails, we can just return an empty string.
But if the status code is 500, there may not be a body. if there is, it will be a json object with a message key. we need to try to parse it, but if it fails, we can just return an empty string
*/
func TryParseErrorBody(res *resty.Response) string {
if res == nil || !res.IsError() {
return ""
}
body := res.String()
if body == "" {
return ""
}
type ErrorResponse struct {
Message string `json:"message"`
ReqId string `json:"reqId"`
}
// stringify zod body entirely
if res.StatusCode() == 422 {
return body
}
// now we have a string, we need to try to parse it as json
var errorResponse ErrorResponse
err := json.Unmarshal([]byte(body), &errorResponse)
if err != nil {
return ""
}
return errorResponse.Message
}
func TryExtractReqId(res *resty.Response) string {
if res == nil || !res.IsError() {
return ""
}
type ErrorResponse struct {
ReqId string `json:"reqId"`
}
var errorResponse ErrorResponse
err := json.Unmarshal([]byte(res.String()), &errorResponse)
if err != nil {
return ""
}
return errorResponse.ReqId
}
func SleepWithContext(ctx context.Context, duration time.Duration) error {
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(duration):
return nil
}
}
func ComputeCacheKeyFromBytes(bytes []byte, feature string) string {
key := sha256.Sum256(bytes)
return fmt.Sprintf("%s-%s", feature, hex.EncodeToString(key[:]))
}

158
vendor/github.com/infisical/go-sdk/secrets.go generated vendored Normal file
View File

@@ -0,0 +1,158 @@
package infisical
import (
"os"
api "github.com/infisical/go-sdk/packages/api/secrets"
"github.com/infisical/go-sdk/packages/models"
"github.com/infisical/go-sdk/packages/util"
)
type ListSecretsOptions = api.ListSecretsV3RawRequest
type RetrieveSecretOptions = api.RetrieveSecretV3RawRequest
type UpdateSecretOptions = api.UpdateSecretV3RawRequest
type CreateSecretOptions = api.CreateSecretV3RawRequest
type DeleteSecretOptions = api.DeleteSecretV3RawRequest
type BatchCreateSecret = api.BatchCreateSecret
type SecretMetadata = models.SecretMetadata
type BatchCreateSecretsOptions = api.BatchCreateSecretsV3RawRequest
type BatchSecretsInterface interface {
Create(options BatchCreateSecretsOptions) ([]models.Secret, error)
}
type ListSecretsResult struct {
Secrets []models.Secret
ETag string
}
type SecretsInterface interface {
// Deprecated: Use ListSecrets instead for ETag-based caching support.
List(options ListSecretsOptions) ([]models.Secret, error)
ListSecrets(options ListSecretsOptions) (ListSecretsResult, error)
Retrieve(options RetrieveSecretOptions) (models.Secret, error)
Update(options UpdateSecretOptions) (models.Secret, error)
Create(options CreateSecretOptions) (models.Secret, error)
Delete(options DeleteSecretOptions) (models.Secret, error)
Batch() BatchSecretsInterface
}
type Secrets struct {
client *InfisicalClient
}
type BatchSecrets struct {
client *InfisicalClient
}
// Deprecated: Use ListSecrets instead for ETag-based caching support.
func (s *Secrets) List(options ListSecretsOptions) ([]models.Secret, error) {
result, err := s.ListSecrets(options)
if err != nil {
return nil, err
}
return result.Secrets, nil
}
func (s *Secrets) ListSecrets(options ListSecretsOptions) (ListSecretsResult, error) {
res, err := api.CallListSecretsV3(s.client.cache, s.client.httpClient, options)
if err != nil {
return ListSecretsResult{}, err
}
if options.Recursive {
util.EnsureUniqueSecretsByKey(&res.Secrets, options.SkipUniqueValidation)
}
secrets := append([]models.Secret(nil), res.Secrets...) // Clone main secrets slice, we will modify this if imports are enabled
if options.IncludeImports {
// Append secrets from imports
for _, importBlock := range res.Imports {
for _, importSecret := range importBlock.Secrets {
// Only append the secret if it is not already in the list, imports take precedence
if !util.ContainsSecret(secrets, importSecret.SecretKey) {
secrets = append(secrets, importSecret)
}
}
}
}
if options.AttachToProcessEnv {
for _, secret := range secrets {
// Only set the environment variable if it is not already set
if os.Getenv(secret.SecretKey) == "" {
_ = os.Setenv(secret.SecretKey, secret.SecretValue)
}
}
}
return ListSecretsResult{
Secrets: util.SortSecretsByKeys(secrets),
ETag: res.ETag,
}, nil
}
func (s *Secrets) Retrieve(options RetrieveSecretOptions) (models.Secret, error) {
res, err := api.CallRetrieveSecretV3(s.client.cache, s.client.httpClient, options)
if err != nil {
return models.Secret{}, err
}
return res.Secret, nil
}
func (s *Secrets) Update(options UpdateSecretOptions) (models.Secret, error) {
res, err := api.CallUpdateSecretV3(s.client.httpClient, options)
if err != nil {
return models.Secret{}, err
}
return res.Secret, nil
}
func (s *Secrets) Create(options CreateSecretOptions) (models.Secret, error) {
res, err := api.CallCreateSecretV3(s.client.httpClient, options)
if err != nil {
return models.Secret{}, err
}
return res.Secret, nil
}
func (s *Secrets) Delete(options DeleteSecretOptions) (models.Secret, error) {
res, err := api.CallDeleteSecretV3(s.client.httpClient, options)
if err != nil {
return models.Secret{}, err
}
return res.Secret, nil
}
// Batch operations
func (bs *BatchSecrets) Create(options BatchCreateSecretsOptions) ([]models.Secret, error) {
res, err := api.CallBatchCreateSecretV3(bs.client.httpClient, options)
if err != nil {
return nil, err
}
return res.Secrets, nil
}
func (s *Secrets) Batch() BatchSecretsInterface {
return &BatchSecrets{client: s.client}
}
func NewSecrets(client *InfisicalClient) SecretsInterface {
return &Secrets{client: client}
}

105
vendor/github.com/infisical/go-sdk/ssh.go generated vendored Normal file
View File

@@ -0,0 +1,105 @@
package infisical
import (
api "github.com/infisical/go-sdk/packages/api/ssh"
)
type SignSshPublicKeyOptions = api.SignSshPublicKeyV1Request
type IssueSshCredsOptions = api.IssueSshCredsV1Request
type GetSshHostsOptions = api.GetSshHostsV1Request
type IssueSshHostUserCertOptions = api.IssueSshHostUserCertV1Request
type IssueSshHostHostCertOptions = api.IssueSshHostHostCertV1Request
type AddSshHostOptions = api.AddSshHostV1Request
type SshInterface interface {
SignKey(options SignSshPublicKeyOptions) (api.SignSshPublicKeyV1Response, error)
IssueCredentials(options IssueSshCredsOptions) (api.IssueSshCredsV1Response, error)
GetSshHosts(options GetSshHostsOptions) (api.GetSshHostsV1Response, error)
GetSshHostUserCaPublicKey(sshHostId string) (string, error)
GetSshHostHostCaPublicKey(sshHostId string) (string, error)
IssueSshHostUserCert(sshHostId string, options IssueSshHostUserCertOptions) (api.IssueSshHostUserCertV1Response, error)
IssueSshHostHostCert(sshHostId string, options IssueSshHostHostCertOptions) (api.IssueSshHostHostCertV1Response, error)
AddSshHost(options AddSshHostOptions) (api.AddSshHostV1Response, error)
}
type Ssh struct {
client *InfisicalClient
}
func (f *Ssh) SignKey(options SignSshPublicKeyOptions) (api.SignSshPublicKeyV1Response, error) {
res, err := api.CallSignSshPublicKeyV1(f.client.httpClient, options)
if err != nil {
return api.SignSshPublicKeyV1Response{}, err
}
return res, nil
}
func (f *Ssh) IssueCredentials(options IssueSshCredsOptions) (api.IssueSshCredsV1Response, error) {
res, err := api.CallIssueSshCredsV1(f.client.httpClient, options)
if err != nil {
return api.IssueSshCredsV1Response{}, err
}
return res, nil
}
func (f *Ssh) GetSshHosts(options GetSshHostsOptions) (api.GetSshHostsV1Response, error) {
res, err := api.GetSshHostsV1(f.client.httpClient, options)
if err != nil {
return api.GetSshHostsV1Response{}, err
}
return res, nil
}
func (f *Ssh) GetSshHostUserCaPublicKey(sshHostId string) (string, error) {
res, err := api.GetSshHostUserCaPublicKeyV1(f.client.httpClient, sshHostId)
if err != nil {
return "", err
}
return res, nil
}
func (f *Ssh) GetSshHostHostCaPublicKey(sshHostId string) (string, error) {
res, err := api.GetSshHostHostCaPublicKeyV1(f.client.httpClient, sshHostId)
if err != nil {
return "", err
}
return res, nil
}
func (f *Ssh) IssueSshHostUserCert(sshHostId string, options IssueSshHostUserCertOptions) (api.IssueSshHostUserCertV1Response, error) {
res, err := api.CallIssueSshHostUserCertV1(f.client.httpClient, sshHostId, options)
if err != nil {
return api.IssueSshHostUserCertV1Response{}, err
}
return res, nil
}
func (f *Ssh) IssueSshHostHostCert(sshHostId string, options IssueSshHostHostCertOptions) (api.IssueSshHostHostCertV1Response, error) {
res, err := api.CallIssueSshHostHostCertV1(f.client.httpClient, sshHostId, options)
if err != nil {
return api.IssueSshHostHostCertV1Response{}, err
}
return res, nil
}
func (f *Ssh) AddSshHost(options AddSshHostOptions) (api.AddSshHostV1Response, error) {
res, err := api.CallAddSshHostV1(f.client.httpClient, options)
if err != nil {
return api.AddSshHostV1Response{}, err
}
return res, nil
}
func NewSsh(client *InfisicalClient) SshInterface {
return &Ssh{client: client}
}