backend/manta: Update triton-go dependency to 1.1.1
This will support the features of RBAC in Manta Backends
This commit is contained in:
parent
9cef4674c5
commit
78525fd65a
|
@ -1,39 +1,62 @@
|
|||
## Unreleased
|
||||
|
||||
- Add support for managing columes in Triton [#100]
|
||||
## 1.1.1 (March 13 2018)
|
||||
|
||||
- client: Adding the rbac user support to the SSHAgentSigner [BUG!]
|
||||
|
||||
## 1.1.0 (March 13 2018)
|
||||
|
||||
- client: Add support for Manta RBAC http signatures
|
||||
|
||||
## 1.0.0 (February 28 2018)
|
||||
|
||||
- client: Add support for querystring in client/ExecuteRequestRaw [#121]
|
||||
- client: Introduce SetHeader for overriding API request header [#125]
|
||||
- compute/instances: Add support for passing a list of tags to filter List instances [#116]
|
||||
- compute/instances: Add support for getting a count of current instances from the CloudAPI [#119]
|
||||
- compute/instances: Add ability to support name-prefix [#129]
|
||||
- compute/instances: Add support for Instance Deletion Protection [#131]
|
||||
- identity/user: Add support for ChangeUserPassword [#111]
|
||||
- expose GetTritonEnv as a root level func [#126]
|
||||
|
||||
## 0.9.0 (January 23 2018)
|
||||
|
||||
**Please Note:** This is a precursor release to marking triton-go as 1.0.0. We are going to wait and fix any bugs that occur from this large set of changes that has happened since 0.5.2
|
||||
|
||||
- Add support for managing volumes in Triton [#100]
|
||||
- identity/policies: Add support for managing policies in Triton [#86]
|
||||
- addition of triton-go errors package to expose unwraping of internal errors
|
||||
- addition of triton-go errors package to expose unwrapping of internal errors
|
||||
- Migration from hashicorp/errwrap to pkg/errors
|
||||
- Using path.Join() for URL structures rather than fmt.Sprintf()
|
||||
|
||||
## 0.5.2 (December 28)
|
||||
## 0.5.2 (December 28 2017)
|
||||
|
||||
- Standardise the API SSH Signers input casing and naming
|
||||
|
||||
## 0.5.1 (December 28)
|
||||
## 0.5.1 (December 28 2017)
|
||||
|
||||
- Include leading '/' when working with SSH Agent signers
|
||||
|
||||
## 0.5.0 (December 28)
|
||||
## 0.5.0 (December 28 2017)
|
||||
|
||||
- Add support for RBAC in triton-go [#82]
|
||||
This is a breaking change. No longer do we pass individual parameters to the SSH Signer funcs, but we now pass an input Struct. This will guard from from additional parameter changes in the future.
|
||||
We also now add support for using `SDC_*` and `TRITON_*` env vars when working with the Default agent signer
|
||||
|
||||
## 0.4.2 (December 22)
|
||||
## 0.4.2 (December 22 2017)
|
||||
|
||||
- Fixing a panic when the user loses network connectivity when making a GET request to instance [#81]
|
||||
|
||||
## 0.4.1 (December 15)
|
||||
## 0.4.1 (December 15 2017)
|
||||
|
||||
- Clean up the handling of directory sanitization. Use abs paths everywhere [#79]
|
||||
|
||||
## 0.4.0 (December 15)
|
||||
## 0.4.0 (December 15 2017)
|
||||
|
||||
- Fix an issue where Manta HEAD requests do not return an error resp body [#77]
|
||||
- Add support for recursively creating child directories [#78]
|
||||
|
||||
## 0.3.0 (December 14)
|
||||
## 0.3.0 (December 14 2017)
|
||||
|
||||
- Introduce CloudAPI's ListRulesMachines under networking
|
||||
- Enable HTTP KeepAlives by default in the client. 15s idle timeout, 2x
|
||||
|
@ -46,11 +69,11 @@ We also now add support for using `SDC_*` and `TRITON_*` env vars when working w
|
|||
- Add support for ForceDelete of all children of a directory [#71](https://github.com/joyent/issues/71)
|
||||
- storage: Introduce `Objects.GetInfo` and `Objects.IsDir` using HEAD requests [#74](https://github.com/joyent/triton-go/issues/74)
|
||||
|
||||
## 0.2.1 (November 8)
|
||||
## 0.2.1 (November 8 2017)
|
||||
|
||||
- Fixing a bug where CreateUser and UpdateUser didn't return the UserID
|
||||
|
||||
## 0.2.0 (November 7)
|
||||
## 0.2.0 (November 7 2017)
|
||||
|
||||
- Introduce CloudAPI's Ping under compute
|
||||
- Introduce CloudAPI's RebootMachine under compute instances
|
||||
|
@ -59,6 +82,6 @@ We also now add support for using `SDC_*` and `TRITON_*` env vars when working w
|
|||
- tools: Introduce unit testing and scripts for linting, etc.
|
||||
- bug: Fix the `compute.ListMachineRules` endpoint
|
||||
|
||||
## 0.1.0 (November 2)
|
||||
## 0.1.0 (November 2 2017)
|
||||
|
||||
- Initial release of a versioned SDK
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
TEST?=$$(go list ./... |grep -Ev 'vendor|examples|testutils')
|
||||
GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor)
|
||||
|
||||
default: vet errcheck test
|
||||
default: vet fmtcheck errcheck test
|
||||
|
||||
tools:: ## Download and install all dev/code tools
|
||||
@echo "==> Installing dev tools"
|
||||
|
@ -29,16 +29,16 @@ vet:: ## Check for unwanted code constructs
|
|||
fi
|
||||
|
||||
lint:: ## Lint and vet code by common Go standards
|
||||
@bash $(CURDIR)/scripts/lint.sh
|
||||
@./scripts/lint.sh
|
||||
|
||||
fmt:: ## Format as canonical Go code
|
||||
gofmt -w $(GOFMT_FILES)
|
||||
|
||||
fmtcheck:: ## Check if code format is canonical Go
|
||||
@bash $(CURDIR)/scripts/gofmtcheck.sh
|
||||
@./scripts/gofmtcheck.sh
|
||||
|
||||
errcheck:: ## Check for unhandled errors
|
||||
@bash $(CURDIR)/scripts/errcheck.sh
|
||||
@./scripts/errcheck.sh
|
||||
|
||||
.PHONY: help
|
||||
help:: ## Display this help message
|
||||
|
|
|
@ -5,6 +5,15 @@ using Joyent's Triton Compute and Storage (Manta) APIs.
|
|||
|
||||
[![Build Status](https://travis-ci.org/joyent/triton-go.svg?branch=master)](https://travis-ci.org/joyent/triton-go) [![Go Report Card](https://goreportcard.com/badge/github.com/joyent/triton-go)](https://goreportcard.com/report/github.com/joyent/triton-go)
|
||||
|
||||
The Triton Go SDK is used in the following open source projects.
|
||||
|
||||
- [Packer](http://github.com/hashicorp/packer)
|
||||
- [Vault](http://github.com/hashicorp/vault)
|
||||
- [Terraform](http://github.com/hashicorp/terraform)
|
||||
- [Terraform Triton Provider](https://github.com/terraform-providers/terraform-provider-triton)
|
||||
- [Docker Machine](https://github.com/joyent/docker-machine-driver-triton)
|
||||
- [Triton Kubernetes](https://github.com/joyent/triton-kubernetes)
|
||||
|
||||
## Usage
|
||||
|
||||
Triton uses [HTTP Signature][4] to sign the Date header in each HTTP request
|
||||
|
@ -38,7 +47,7 @@ ssh-keygen -Emd5 -lf ~/.ssh/id_rsa.pub | cut -d " " -f 2 | sed 's/MD5://'
|
|||
```
|
||||
|
||||
Each top level package, `account`, `compute`, `identity`, `network`, all have
|
||||
their own seperate client. In order to initialize a package client, simply pass
|
||||
their own separate client. In order to initialize a package client, simply pass
|
||||
the global `triton.ClientConfig` struct into the client's constructor function.
|
||||
|
||||
```go
|
||||
|
@ -73,8 +82,8 @@ if err != nil {
|
|||
## Error Handling
|
||||
|
||||
If an error is returned by the HTTP API, the `error` returned from the function
|
||||
will contain an instance of `compute.TritonError` in the chain. Error wrapping
|
||||
is performed using the [errwrap][7] library from HashiCorp.
|
||||
will contain an instance of `errors.APIError` in the chain. Error wrapping
|
||||
is performed using the [pkg/errors][7] library.
|
||||
|
||||
## Acceptance Tests
|
||||
|
||||
|
@ -235,4 +244,4 @@ func main() {
|
|||
[4]: https://github.com/joyent/node-http-signature/blob/master/http_signing.md
|
||||
[5]: https://godoc.org/github.com/joyent/triton-go/authentication
|
||||
[6]: https://godoc.org/github.com/joyent/triton-go/authentication
|
||||
[7]: https://github.com/hashicorp/go-errwrap
|
||||
[7]: https://github.com/pkg/errors
|
||||
|
|
25
vendor/github.com/joyent/triton-go/authentication/agent_key_identifier.go
generated
vendored
Normal file
25
vendor/github.com/joyent/triton-go/authentication/agent_key_identifier.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
package authentication
|
||||
|
||||
import "path"
|
||||
|
||||
type KeyID struct {
|
||||
UserName string
|
||||
AccountName string
|
||||
Fingerprint string
|
||||
IsManta bool
|
||||
}
|
||||
|
||||
func (input *KeyID) generate() string {
|
||||
var keyID string
|
||||
if input.UserName != "" {
|
||||
if input.IsManta {
|
||||
keyID = path.Join("/", input.AccountName, input.UserName, "keys", input.Fingerprint)
|
||||
} else {
|
||||
keyID = path.Join("/", input.AccountName, "users", input.UserName, "keys", input.Fingerprint)
|
||||
}
|
||||
} else {
|
||||
keyID = path.Join("/", input.AccountName, "keys", input.Fingerprint)
|
||||
}
|
||||
|
||||
return keyID
|
||||
}
|
|
@ -16,7 +16,6 @@ import (
|
|||
"encoding/base64"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
@ -87,7 +86,7 @@ func NewPrivateKeySigner(input PrivateKeySignerInput) (*PrivateKeySigner, error)
|
|||
return signer, nil
|
||||
}
|
||||
|
||||
func (s *PrivateKeySigner) Sign(dateHeader string) (string, error) {
|
||||
func (s *PrivateKeySigner) Sign(dateHeader string, isManta bool) (string, error) {
|
||||
const headerName = "date"
|
||||
|
||||
hash := s.hashFunc.New()
|
||||
|
@ -100,14 +99,14 @@ func (s *PrivateKeySigner) Sign(dateHeader string) (string, error) {
|
|||
}
|
||||
signedBase64 := base64.StdEncoding.EncodeToString(signed)
|
||||
|
||||
var keyID string
|
||||
if s.userName != "" {
|
||||
|
||||
keyID = path.Join("/", s.accountName, "users", s.userName, "keys", s.formattedKeyFingerprint)
|
||||
} else {
|
||||
keyID = path.Join("/", s.accountName, "keys", s.formattedKeyFingerprint)
|
||||
key := &KeyID{
|
||||
UserName: s.userName,
|
||||
AccountName: s.accountName,
|
||||
Fingerprint: s.formattedKeyFingerprint,
|
||||
IsManta: isManta,
|
||||
}
|
||||
return fmt.Sprintf(authorizationHeaderFormat, keyID, "rsa-sha1", headerName, signedBase64), nil
|
||||
|
||||
return fmt.Sprintf(authorizationHeaderFormat, key.generate(), "rsa-sha1", headerName, signedBase64), nil
|
||||
}
|
||||
|
||||
func (s *PrivateKeySigner) SignRaw(toSign string) (string, string, error) {
|
||||
|
|
|
@ -13,6 +13,6 @@ const authorizationHeaderFormat = `Signature keyId="%s",algorithm="%s",headers="
|
|||
type Signer interface {
|
||||
DefaultAlgorithm() string
|
||||
KeyFingerprint() string
|
||||
Sign(dateHeader string) (string, error)
|
||||
Sign(dateHeader string, isManta bool) (string, error)
|
||||
SignRaw(toSign string) (string, string, error)
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
pkgerrors "github.com/pkg/errors"
|
||||
|
@ -64,18 +63,16 @@ func NewSSHAgentSigner(input SSHAgentSignerInput) (*SSHAgentSigner, error) {
|
|||
agent: ag,
|
||||
}
|
||||
|
||||
if input.Username != "" {
|
||||
signer.userName = input.Username
|
||||
}
|
||||
|
||||
matchingKey, err := signer.MatchKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
signer.key = matchingKey
|
||||
signer.formattedKeyFingerprint = formatPublicKeyFingerprint(signer.key, true)
|
||||
if input.Username != "" {
|
||||
signer.userName = input.Username
|
||||
signer.keyIdentifier = path.Join("/", signer.accountName, "users", input.Username, "keys", signer.formattedKeyFingerprint)
|
||||
} else {
|
||||
signer.keyIdentifier = path.Join("/", signer.accountName, "keys", signer.formattedKeyFingerprint)
|
||||
}
|
||||
|
||||
_, algorithm, err := signer.SignRaw("HelloWorld")
|
||||
if err != nil {
|
||||
|
@ -118,7 +115,7 @@ func (s *SSHAgentSigner) MatchKey() (ssh.PublicKey, error) {
|
|||
return matchingKey, nil
|
||||
}
|
||||
|
||||
func (s *SSHAgentSigner) Sign(dateHeader string) (string, error) {
|
||||
func (s *SSHAgentSigner) Sign(dateHeader string, isManta bool) (string, error) {
|
||||
const headerName = "date"
|
||||
|
||||
signature, err := s.agent.Sign(s.key, []byte(fmt.Sprintf("%s: %s", headerName, dateHeader)))
|
||||
|
@ -131,6 +128,13 @@ func (s *SSHAgentSigner) Sign(dateHeader string) (string, error) {
|
|||
return "", pkgerrors.Wrap(err, "unable to format signature")
|
||||
}
|
||||
|
||||
key := &KeyID{
|
||||
UserName: s.userName,
|
||||
AccountName: s.accountName,
|
||||
Fingerprint: s.formattedKeyFingerprint,
|
||||
IsManta: isManta,
|
||||
}
|
||||
|
||||
var authSignature httpAuthSignature
|
||||
switch keyFormat {
|
||||
case "rsa":
|
||||
|
@ -147,7 +151,7 @@ func (s *SSHAgentSigner) Sign(dateHeader string) (string, error) {
|
|||
return "", fmt.Errorf("Unsupported algorithm from SSH agent: %s", signature.Format)
|
||||
}
|
||||
|
||||
return fmt.Sprintf(authorizationHeaderFormat, s.keyIdentifier,
|
||||
return fmt.Sprintf(authorizationHeaderFormat, key.generate(),
|
||||
authSignature.SignatureType(), headerName, authSignature.String()), nil
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ func (s *TestSigner) KeyFingerprint() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (s *TestSigner) Sign(dateHeader string) (string, error) {
|
||||
func (s *TestSigner) Sign(dateHeader string, isManta bool) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/joyent/triton-go"
|
||||
|
@ -41,6 +40,7 @@ var (
|
|||
// Client represents a connection to the Triton Compute or Object Storage APIs.
|
||||
type Client struct {
|
||||
HTTPClient *http.Client
|
||||
RequestHeader *http.Header
|
||||
Authorizers []authentication.Signer
|
||||
TritonURL url.URL
|
||||
MantaURL url.URL
|
||||
|
@ -102,29 +102,12 @@ func New(tritonURL string, mantaURL string, accountName string, signers ...authe
|
|||
return newClient, nil
|
||||
}
|
||||
|
||||
var envPrefixes = []string{"TRITON", "SDC"}
|
||||
|
||||
// GetTritonEnv looks up environment variables using the preferred "TRITON"
|
||||
// prefix, but falls back to the SDC prefix. For example, looking up "USER"
|
||||
// will search for "TRITON_USER" followed by "SDC_USER". If the environment
|
||||
// variable is not set, an empty string is returned. GetTritonEnv() is used to
|
||||
// aid in the transition and deprecation of the SDC_* environment variables.
|
||||
func GetTritonEnv(name string) string {
|
||||
for _, prefix := range envPrefixes {
|
||||
if val, found := os.LookupEnv(prefix + "_" + name); found {
|
||||
return val
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// initDefaultAuth provides a default key signer for a client. This should only
|
||||
// be used internally if the client has no other key signer for authenticating
|
||||
// with Triton. We first look for both `SDC_KEY_ID` and `SSH_AUTH_SOCK` in the
|
||||
// user's environ(7). If so we default to the SSH agent key signer.
|
||||
func (c *Client) DefaultAuth() error {
|
||||
tritonKeyId := GetTritonEnv("KEY_ID")
|
||||
tritonKeyId := triton.GetEnv("KEY_ID")
|
||||
if tritonKeyId != "" {
|
||||
input := authentication.SSHAgentSignerInput{
|
||||
KeyID: tritonKeyId,
|
||||
|
@ -153,6 +136,8 @@ func (c *Client) InsecureSkipTLSVerify() {
|
|||
c.HTTPClient.Transport = httpTransport(true)
|
||||
}
|
||||
|
||||
// httpTransport is responsible for setting up our HTTP client's transport
|
||||
// settings
|
||||
func httpTransport(insecureSkipTLSVerify bool) *http.Transport {
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
|
@ -173,6 +158,7 @@ func doNotFollowRedirects(*http.Request, []*http.Request) error {
|
|||
return http.ErrUseLastResponse
|
||||
}
|
||||
|
||||
// DecodeError decodes a backend Triton error into a more usable Go error type
|
||||
func (c *Client) DecodeError(resp *http.Response, requestMethod string) error {
|
||||
err := &errors.APIError{
|
||||
StatusCode: resp.StatusCode,
|
||||
|
@ -192,6 +178,23 @@ func (c *Client) DecodeError(resp *http.Response, requestMethod string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// overrideHeader overrides the header of the passed in HTTP request
|
||||
func (c *Client) overrideHeader(req *http.Request) {
|
||||
if c.RequestHeader != nil {
|
||||
for k, vs := range *c.RequestHeader {
|
||||
for _, v := range vs {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// resetHeader will reset the struct field that stores custom header
|
||||
// information
|
||||
func (c *Client) resetHeader() {
|
||||
c.RequestHeader = nil
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
type RequestInput struct {
|
||||
|
@ -203,6 +206,8 @@ type RequestInput struct {
|
|||
}
|
||||
|
||||
func (c *Client) ExecuteRequestURIParams(ctx context.Context, inputs RequestInput) (io.ReadCloser, error) {
|
||||
defer c.resetHeader()
|
||||
|
||||
method := inputs.Method
|
||||
path := inputs.Path
|
||||
body := inputs.Body
|
||||
|
@ -233,7 +238,7 @@ func (c *Client) ExecuteRequestURIParams(ctx context.Context, inputs RequestInpu
|
|||
|
||||
// NewClient ensures there's always an authorizer (unless this is called
|
||||
// outside that constructor).
|
||||
authHeader, err := c.Authorizers[0].Sign(dateHeader)
|
||||
authHeader, err := c.Authorizers[0].Sign(dateHeader, false)
|
||||
if err != nil {
|
||||
return nil, pkgerrors.Wrapf(err, "unable to sign HTTP request")
|
||||
}
|
||||
|
@ -246,6 +251,8 @@ func (c *Client) ExecuteRequestURIParams(ctx context.Context, inputs RequestInpu
|
|||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
c.overrideHeader(req)
|
||||
|
||||
resp, err := c.HTTPClient.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, pkgerrors.Wrapf(err, "unable to execute HTTP request")
|
||||
|
@ -265,9 +272,12 @@ func (c *Client) ExecuteRequest(ctx context.Context, inputs RequestInput) (io.Re
|
|||
}
|
||||
|
||||
func (c *Client) ExecuteRequestRaw(ctx context.Context, inputs RequestInput) (*http.Response, error) {
|
||||
defer c.resetHeader()
|
||||
|
||||
method := inputs.Method
|
||||
path := inputs.Path
|
||||
body := inputs.Body
|
||||
query := inputs.Query
|
||||
|
||||
var requestBody io.Reader
|
||||
if body != nil {
|
||||
|
@ -280,6 +290,9 @@ func (c *Client) ExecuteRequestRaw(ctx context.Context, inputs RequestInput) (*h
|
|||
|
||||
endpoint := c.TritonURL
|
||||
endpoint.Path = path
|
||||
if query != nil {
|
||||
endpoint.RawQuery = query.Encode()
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, endpoint.String(), requestBody)
|
||||
if err != nil {
|
||||
|
@ -291,7 +304,7 @@ func (c *Client) ExecuteRequestRaw(ctx context.Context, inputs RequestInput) (*h
|
|||
|
||||
// NewClient ensures there's always an authorizer (unless this is called
|
||||
// outside that constructor).
|
||||
authHeader, err := c.Authorizers[0].Sign(dateHeader)
|
||||
authHeader, err := c.Authorizers[0].Sign(dateHeader, false)
|
||||
if err != nil {
|
||||
return nil, pkgerrors.Wrapf(err, "unable to sign HTTP request")
|
||||
}
|
||||
|
@ -304,6 +317,8 @@ func (c *Client) ExecuteRequestRaw(ctx context.Context, inputs RequestInput) (*h
|
|||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
c.overrideHeader(req)
|
||||
|
||||
resp, err := c.HTTPClient.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, pkgerrors.Wrapf(err, "unable to execute HTTP request")
|
||||
|
@ -319,6 +334,8 @@ func (c *Client) ExecuteRequestRaw(ctx context.Context, inputs RequestInput) (*h
|
|||
}
|
||||
|
||||
func (c *Client) ExecuteRequestStorage(ctx context.Context, inputs RequestInput) (io.ReadCloser, http.Header, error) {
|
||||
defer c.resetHeader()
|
||||
|
||||
method := inputs.Method
|
||||
path := inputs.Path
|
||||
query := inputs.Query
|
||||
|
@ -356,7 +373,7 @@ func (c *Client) ExecuteRequestStorage(ctx context.Context, inputs RequestInput)
|
|||
dateHeader := time.Now().UTC().Format(time.RFC1123)
|
||||
req.Header.Set("date", dateHeader)
|
||||
|
||||
authHeader, err := c.Authorizers[0].Sign(dateHeader)
|
||||
authHeader, err := c.Authorizers[0].Sign(dateHeader, true)
|
||||
if err != nil {
|
||||
return nil, nil, pkgerrors.Wrapf(err, "unable to sign HTTP request")
|
||||
}
|
||||
|
@ -368,6 +385,8 @@ func (c *Client) ExecuteRequestStorage(ctx context.Context, inputs RequestInput)
|
|||
req.URL.RawQuery = query.Encode()
|
||||
}
|
||||
|
||||
c.overrideHeader(req)
|
||||
|
||||
resp, err := c.HTTPClient.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, nil, pkgerrors.Wrapf(err, "unable to execute HTTP request")
|
||||
|
@ -391,6 +410,8 @@ type RequestNoEncodeInput struct {
|
|||
}
|
||||
|
||||
func (c *Client) ExecuteRequestNoEncode(ctx context.Context, inputs RequestNoEncodeInput) (io.ReadCloser, http.Header, error) {
|
||||
defer c.resetHeader()
|
||||
|
||||
method := inputs.Method
|
||||
path := inputs.Path
|
||||
query := inputs.Query
|
||||
|
@ -416,7 +437,7 @@ func (c *Client) ExecuteRequestNoEncode(ctx context.Context, inputs RequestNoEnc
|
|||
dateHeader := time.Now().UTC().Format(time.RFC1123)
|
||||
req.Header.Set("date", dateHeader)
|
||||
|
||||
authHeader, err := c.Authorizers[0].Sign(dateHeader)
|
||||
authHeader, err := c.Authorizers[0].Sign(dateHeader, true)
|
||||
if err != nil {
|
||||
return nil, nil, pkgerrors.Wrapf(err, "unable to sign HTTP request")
|
||||
}
|
||||
|
@ -429,6 +450,8 @@ func (c *Client) ExecuteRequestNoEncode(ctx context.Context, inputs RequestNoEnc
|
|||
req.URL.RawQuery = query.Encode()
|
||||
}
|
||||
|
||||
c.overrideHeader(req)
|
||||
|
||||
resp, err := c.HTTPClient.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, nil, pkgerrors.Wrapf(err, "unable to execute HTTP request")
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
triton "github.com/joyent/triton-go"
|
||||
"github.com/joyent/triton-go/client"
|
||||
)
|
||||
|
@ -34,6 +36,12 @@ func NewClient(config *triton.ClientConfig) (*StorageClient, error) {
|
|||
return newStorageClient(client), nil
|
||||
}
|
||||
|
||||
// SetHeader allows a consumer of the current client to set a custom header for
|
||||
// the next backend HTTP request sent to CloudAPI.
|
||||
func (c *StorageClient) SetHeader(header *http.Header) {
|
||||
c.Client.RequestHeader = header
|
||||
}
|
||||
|
||||
// Dir returns a DirectoryClient used for accessing functions pertaining to
|
||||
// Directories functionality of the Manta API.
|
||||
func (c *StorageClient) Dir() *DirectoryClient {
|
||||
|
|
|
@ -102,7 +102,7 @@ type PutDirectoryInput struct {
|
|||
DirectoryName string
|
||||
}
|
||||
|
||||
// Put puts a directoy into the Triton Object Storage service is an idempotent
|
||||
// Put puts a director into the Triton Object Storage service is an idempotent
|
||||
// create-or-update operation. Your private namespace starts at /:login, and you
|
||||
// can create any nested set of directories or objects within it.
|
||||
func (s *DirectoryClient) Put(ctx context.Context, input *PutDirectoryInput) error {
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/joyent/triton-go/authentication"
|
||||
)
|
||||
|
||||
|
@ -25,3 +27,20 @@ type ClientConfig struct {
|
|||
Username string
|
||||
Signers []authentication.Signer
|
||||
}
|
||||
|
||||
var envPrefixes = []string{"TRITON", "SDC"}
|
||||
|
||||
// GetEnv looks up environment variables using the preferred "TRITON" prefix,
|
||||
// but falls back to the retired "SDC" prefix. For example, looking up "USER"
|
||||
// will search for "TRITON_USER" followed by "SDC_USER". If the environment
|
||||
// variable is not set, an empty string is returned. GetEnv() is used to aid in
|
||||
// the transition and deprecation of the "SDC_*" environment variables.
|
||||
func GetEnv(name string) string {
|
||||
for _, prefix := range envPrefixes {
|
||||
if val, found := os.LookupEnv(prefix + "_" + name); found {
|
||||
return val
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -13,20 +13,30 @@ import (
|
|||
"runtime"
|
||||
)
|
||||
|
||||
// The main version number of the current released Triton-go SDK.
|
||||
const Version = "0.9.0"
|
||||
// Version represents main version number of the current release
|
||||
// of the Triton-go SDK.
|
||||
const Version = "1.1.1"
|
||||
|
||||
// A pre-release marker for the version. If this is "" (empty string)
|
||||
// then it means that it is a final release. Otherwise, this is a pre-release
|
||||
// such as "dev" (in development), "beta", "rc1", etc.
|
||||
// Prerelease adds a pre-release marker to the version.
|
||||
//
|
||||
// If this is "" (empty string) then it means that it is a final release.
|
||||
// Otherwise, this is a pre-release such as "dev" (in development), "beta",
|
||||
// "rc1", etc.
|
||||
var Prerelease = ""
|
||||
|
||||
// UserAgent returns a Triton-go characteristic string that allows the
|
||||
// network protocol peers to identify the version, release and runtime
|
||||
// of the Triton-go client from which the requests originate.
|
||||
func UserAgent() string {
|
||||
if Prerelease != "" {
|
||||
return fmt.Sprintf("triton-go/%s-%s (%s-%s; %s)", Version, Prerelease, runtime.GOARCH, runtime.GOOS, runtime.Version())
|
||||
} else {
|
||||
return fmt.Sprintf("triton-go/%s (%s-%s; %s)", Version, runtime.GOARCH, runtime.GOOS, runtime.Version())
|
||||
return fmt.Sprintf("triton-go/%s-%s (%s-%s; %s)", Version, Prerelease,
|
||||
runtime.GOARCH, runtime.GOOS, runtime.Version())
|
||||
}
|
||||
|
||||
return fmt.Sprintf("triton-go/%s (%s-%s; %s)", Version, runtime.GOARCH,
|
||||
runtime.GOOS, runtime.Version())
|
||||
}
|
||||
|
||||
// CloudAPIMajorVersion specifies the CloudAPI version compatibility
|
||||
// for current release of the Triton-go SDK.
|
||||
const CloudAPIMajorVersion = "8"
|
||||
|
|
|
@ -1860,34 +1860,44 @@
|
|||
"revisionTime": "2016-08-03T19:07:31Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "Lg8OHK87XRGCaipG+5+zFyN8OMw=",
|
||||
"checksumSHA1": "hnUvydIu2VnSjYP/ROo1SLNlLv4=",
|
||||
"path": "github.com/joyent/triton-go",
|
||||
"revision": "545edbe0d564f075ac576f1ad177f4ff39c9adaf",
|
||||
"revisionTime": "2018-01-16T16:57:42Z"
|
||||
"revision": "d8f9c031492688b4b62b7fd29b1edd9897400c4e",
|
||||
"revisionTime": "2018-03-13T10:08:02Z",
|
||||
"version": "1.1.1",
|
||||
"versionExact": "1.1.1"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "Y03+L+I0FVZ2bMGWt1MHTDEyWM4=",
|
||||
"checksumSHA1": "yNrArK8kjkVkU0bunKlemd6dFkE=",
|
||||
"path": "github.com/joyent/triton-go/authentication",
|
||||
"revision": "545edbe0d564f075ac576f1ad177f4ff39c9adaf",
|
||||
"revisionTime": "2018-01-16T16:57:42Z"
|
||||
"revision": "d8f9c031492688b4b62b7fd29b1edd9897400c4e",
|
||||
"revisionTime": "2018-03-13T10:08:02Z",
|
||||
"version": "1.1.1",
|
||||
"versionExact": "1.1.1"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "MuJsGBr6HlXQYxZY9cM5rBk+Lns=",
|
||||
"checksumSHA1": "WBCMeFCM9qif0JwcGQL72SG7yJM=",
|
||||
"path": "github.com/joyent/triton-go/client",
|
||||
"revision": "545edbe0d564f075ac576f1ad177f4ff39c9adaf",
|
||||
"revisionTime": "2018-01-16T16:57:42Z"
|
||||
"revision": "d8f9c031492688b4b62b7fd29b1edd9897400c4e",
|
||||
"revisionTime": "2018-03-13T10:08:02Z",
|
||||
"version": "1.1.1",
|
||||
"versionExact": "1.1.1"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "d/Py6j/uMgOAFNFGpsQrNnSsO+k=",
|
||||
"path": "github.com/joyent/triton-go/errors",
|
||||
"revision": "545edbe0d564f075ac576f1ad177f4ff39c9adaf",
|
||||
"revisionTime": "2018-01-16T16:57:42Z"
|
||||
"revision": "d8f9c031492688b4b62b7fd29b1edd9897400c4e",
|
||||
"revisionTime": "2018-03-13T10:08:02Z",
|
||||
"version": "1.1.1",
|
||||
"versionExact": "1.1.1"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "5v533ELM047YOiwHsyMaVzITpR0=",
|
||||
"checksumSHA1": "MAjG3M0OLUJ3hdNZLHHpXdl1THQ=",
|
||||
"path": "github.com/joyent/triton-go/storage",
|
||||
"revision": "545edbe0d564f075ac576f1ad177f4ff39c9adaf",
|
||||
"revisionTime": "2018-01-16T16:57:42Z"
|
||||
"revision": "d8f9c031492688b4b62b7fd29b1edd9897400c4e",
|
||||
"revisionTime": "2018-03-13T10:08:02Z",
|
||||
"version": "1.1.1",
|
||||
"versionExact": "1.1.1"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "g+afVQQVopBLiLB5pFZp/8s6aBs=",
|
||||
|
|
Loading…
Reference in New Issue