1
0
Fork 0
hats/pkg/infisical/api.go

127 lines
3.4 KiB
Go

package infisical
import (
"fmt"
"time"
"code.jhot.me/jhot/hats/internal/util"
"github.com/go-resty/resty/v2"
)
type InfisicalClient struct {
restClient *resty.Client
host string
clientId string
clientSecret string
accessToken string
tokenExpiration time.Time
}
func New(host string, clientId string, clientSecret string) *InfisicalClient {
return &InfisicalClient{
restClient: resty.New().SetBaseURL(fmt.Sprintf("%s/api", host)),
host: host,
clientId: clientId,
clientSecret: clientSecret,
accessToken: "",
tokenExpiration: time.Now(),
}
}
func (c *InfisicalClient) Login() error {
var result LoginResponse
_, err := util.CheckSuccess(c.restClient.R().SetFormData(map[string]string{
"clientId": c.clientId,
"clientSecret": c.clientSecret,
}).SetResult(&result).Post("v1/auth/universal-auth/login"))
if err != nil {
return err
}
c.restClient.SetAuthScheme(result.TokenType).SetAuthToken(result.AccessToken)
c.accessToken = result.AccessToken
c.tokenExpiration = time.Now().Add(time.Duration(result.ExpiresIn) * time.Second)
return nil
}
func (c *InfisicalClient) CheckToken() error {
if c.accessToken == "" {
return fmt.Errorf("access token empty, please login first")
}
if time.Now().Before(c.tokenExpiration) {
return nil
}
var result LoginResponse
_, err := util.CheckSuccess(c.restClient.R().SetResult(&result).SetBody(map[string]interface{}{
"accessToken": c.accessToken,
}).Post("v1/auth/token/renew"))
if err != nil {
return fmt.Errorf("error renewing token: %w", err)
}
c.restClient.SetAuthScheme(result.TokenType).SetAuthToken(result.AccessToken)
c.accessToken = result.AccessToken
c.tokenExpiration = time.Now().Add(time.Duration(result.ExpiresIn) * time.Second)
return nil
}
func (c *InfisicalClient) ListSecrets(workspaceId string, environment string, optFuncs ...RetrieveSecretOptionFunc) ([]Secret, error) {
opts := DefaultRetrieveSecretOptions()
optFuncs = append(optFuncs, WithWorkspaceID(workspaceId), WithEnvironment(environment))
for _, f := range optFuncs {
f(opts)
}
err := c.CheckToken()
if err != nil {
return []Secret{}, err
}
var result SecretsResponse
_, err = util.CheckSuccess(c.restClient.R().SetResult(&result).SetQueryParams(map[string]string{
"workspaceId": opts.WorkspaceID,
"environment": opts.Environment,
"secretPath": opts.SecretPath,
"include_imports": fmt.Sprintf("%t", opts.IncludeImports),
}).Get("v3/secrets/raw"))
if err != nil {
return []Secret{}, err
}
return result.Secrets, nil
}
func (c *InfisicalClient) GetSecret(name string, workspaceId string, environment string, optFuncs ...RetrieveSecretOptionFunc) (Secret, error) {
opts := DefaultRetrieveSecretOptions()
optFuncs = append(optFuncs, WithWorkspaceID(workspaceId), WithEnvironment(environment))
for _, f := range optFuncs {
f(opts)
}
err := c.CheckToken()
if err != nil {
return Secret{}, err
}
var result SecretResponse
_, err = util.CheckSuccess(c.restClient.R().SetResult(&result).SetQueryParams(map[string]string{
"workspaceId": opts.WorkspaceID,
"environment": opts.Environment,
"secretPath": opts.SecretPath,
"include_imports": fmt.Sprintf("%t", opts.IncludeImports),
"type": "shared",
}).Get("v3/secrets/raw/" + name))
if err != nil {
return Secret{}, err
}
return result.Secret, nil
}