mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
gateway/manta: Add support for RBAC (#5332)
Manta has the ability to allow users to authenticate with a username other than the main account. We want to expose this functionality to minio manta gateway.
This commit is contained in:
parent
b85c75996d
commit
a1a98617ca
@ -32,7 +32,6 @@ import (
|
|||||||
"github.com/joyent/triton-go/authentication"
|
"github.com/joyent/triton-go/authentication"
|
||||||
tclient "github.com/joyent/triton-go/client"
|
tclient "github.com/joyent/triton-go/client"
|
||||||
"github.com/joyent/triton-go/storage"
|
"github.com/joyent/triton-go/storage"
|
||||||
|
|
||||||
"github.com/minio/cli"
|
"github.com/minio/cli"
|
||||||
minio "github.com/minio/minio/cmd"
|
minio "github.com/minio/minio/cmd"
|
||||||
"github.com/minio/minio/pkg/auth"
|
"github.com/minio/minio/pkg/auth"
|
||||||
@ -68,6 +67,7 @@ ENVIRONMENT VARIABLES:
|
|||||||
MINIO_ACCESS_KEY: The Manta account name.
|
MINIO_ACCESS_KEY: The Manta account name.
|
||||||
MINIO_SECRET_KEY: A KeyID associated with the Manta account.
|
MINIO_SECRET_KEY: A KeyID associated with the Manta account.
|
||||||
MANTA_KEY_MATERIAL: The path to the SSH Key associated with the Manta account if the MINIO_SECRET_KEY is not in SSH Agent.
|
MANTA_KEY_MATERIAL: The path to the SSH Key associated with the Manta account if the MINIO_SECRET_KEY is not in SSH Agent.
|
||||||
|
MANTA_SUBUSER: The username of a user who has limited access to your account.
|
||||||
|
|
||||||
BROWSER:
|
BROWSER:
|
||||||
MINIO_BROWSER: To disable web browser access, set this value to "off".
|
MINIO_BROWSER: To disable web browser access, set this value to "off".
|
||||||
@ -140,7 +140,14 @@ func (g *Manta) NewGatewayLayer(creds auth.Credentials) (minio.GatewayLayer, err
|
|||||||
keyMaterial := os.Getenv("MANTA_KEY_MATERIAL")
|
keyMaterial := os.Getenv("MANTA_KEY_MATERIAL")
|
||||||
|
|
||||||
if keyMaterial == "" {
|
if keyMaterial == "" {
|
||||||
signer, err = authentication.NewSSHAgentSigner(creds.SecretKey, creds.AccessKey)
|
input := authentication.SSHAgentSignerInput{
|
||||||
|
KeyID: creds.SecretKey,
|
||||||
|
AccountName: creds.AccessKey,
|
||||||
|
}
|
||||||
|
if userName, ok := os.LookupEnv("MANTA_SUBUSER"); ok {
|
||||||
|
input.Username = userName
|
||||||
|
}
|
||||||
|
signer, err = authentication.NewSSHAgentSigner(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Trace(err)
|
return nil, errors.Trace(err)
|
||||||
}
|
}
|
||||||
@ -168,7 +175,16 @@ func (g *Manta) NewGatewayLayer(creds auth.Credentials) (minio.GatewayLayer, err
|
|||||||
keyBytes = []byte(keyMaterial)
|
keyBytes = []byte(keyMaterial)
|
||||||
}
|
}
|
||||||
|
|
||||||
signer, err = authentication.NewPrivateKeySigner(creds.SecretKey, keyBytes, creds.AccessKey)
|
input := authentication.PrivateKeySignerInput{
|
||||||
|
KeyID: creds.SecretKey,
|
||||||
|
PrivateKeyMaterial: keyBytes,
|
||||||
|
AccountName: creds.AccessKey,
|
||||||
|
}
|
||||||
|
if userName, ok := os.LookupEnv("MANTA_SUBUSER"); ok {
|
||||||
|
input.Username = userName
|
||||||
|
}
|
||||||
|
|
||||||
|
signer, err = authentication.NewPrivateKeySigner(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Trace(err)
|
return nil, errors.Trace(err)
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,8 @@ Minio Gateway adds Amazon S3 compatibility to Manta Object Storage.
|
|||||||
docker run -p 9000:9000 --name manta-s3 \
|
docker run -p 9000:9000 --name manta-s3 \
|
||||||
-e "MINIO_ACCESS_KEY=joyentaccountname" \
|
-e "MINIO_ACCESS_KEY=joyentaccountname" \
|
||||||
-e "MINIO_SECRET_KEY=joyentkeyid" \
|
-e "MINIO_SECRET_KEY=joyentkeyid" \
|
||||||
-e "MINIO_KEY_MATERIAL=~/.ssh/id_rsa
|
-e "MANTA_KEY_MATERIAL=~/.ssh/id_rsa" \
|
||||||
|
-e "MANTA_SUBUSER=devuser"
|
||||||
minio/minio gateway manta
|
minio/minio gateway manta
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -15,7 +16,8 @@ docker run -p 9000:9000 --name manta-s3 \
|
|||||||
```
|
```
|
||||||
export MINIO_ACCESS_KEY=joyentaccountname
|
export MINIO_ACCESS_KEY=joyentaccountname
|
||||||
export MINIO_SECRET_KEY=joyentkeyid
|
export MINIO_SECRET_KEY=joyentkeyid
|
||||||
export MINIO_KEY_MATERIAL=~/.ssh/id_rsa
|
export MANTA_KEY_MATERIAL=~/.ssh/id_rsa
|
||||||
|
export MANTA_SUBUSER=devuser
|
||||||
minio gateway manta
|
minio gateway manta
|
||||||
```
|
```
|
||||||
## Test using Minio Browser
|
## Test using Minio Browser
|
||||||
|
18
vendor/github.com/joyent/triton-go/CHANGELOG.md
generated
vendored
18
vendor/github.com/joyent/triton-go/CHANGELOG.md
generated
vendored
@ -1,5 +1,23 @@
|
|||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
## 0.5.2 (December 28)
|
||||||
|
|
||||||
|
- Standardise the API SSH Signers input casing and naming
|
||||||
|
|
||||||
|
## 0.5.1 (December 28)
|
||||||
|
|
||||||
|
- Include leading '/' when working with SSH Agent signers
|
||||||
|
|
||||||
|
## 0.5.0 (December 28)
|
||||||
|
|
||||||
|
- 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)
|
||||||
|
|
||||||
|
- 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)
|
||||||
|
|
||||||
- Clean up the handling of directory sanitization. Use abs paths everywhere [#79]
|
- Clean up the handling of directory sanitization. Use abs paths everywhere [#79]
|
||||||
|
87
vendor/github.com/joyent/triton-go/README.md
generated
vendored
87
vendor/github.com/joyent/triton-go/README.md
generated
vendored
@ -15,11 +15,17 @@ using a key stored with the local SSH Agent (using an [`SSHAgentSigner`][6].
|
|||||||
To construct a Signer, use the `New*` range of methods in the `authentication`
|
To construct a Signer, use the `New*` range of methods in the `authentication`
|
||||||
package. In the case of `authentication.NewSSHAgentSigner`, the parameters are
|
package. In the case of `authentication.NewSSHAgentSigner`, the parameters are
|
||||||
the fingerprint of the key with which to sign, and the account name (normally
|
the fingerprint of the key with which to sign, and the account name (normally
|
||||||
stored in the `SDC_ACCOUNT` environment variable). For example:
|
stored in the `TRITON_ACCOUNT` environment variable). There is also support for
|
||||||
|
passing in a username, this will allow you to use an account other than the main
|
||||||
|
Triton account. For example:
|
||||||
|
|
||||||
```
|
```go
|
||||||
const fingerprint := "a4:c6:f3:75:80:27:e0:03:a9:98:79:ef:c5:0a:06:11"
|
input := authentication.SSHAgentSignerInput{
|
||||||
sshKeySigner, err := authentication.NewSSHAgentSigner(fingerprint, "AccountName")
|
KeyID: "a4:c6:f3:75:80:27:e0:03:a9:98:79:ef:c5:0a:06:11",
|
||||||
|
AccountName: "AccountName",
|
||||||
|
Username: "Username",
|
||||||
|
}
|
||||||
|
sshKeySigner, err := authentication.NewSSHAgentSigner(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("NewSSHAgentSigner: %s", err)
|
log.Fatalf("NewSSHAgentSigner: %s", err)
|
||||||
}
|
}
|
||||||
@ -36,17 +42,18 @@ their own seperate client. In order to initialize a package client, simply pass
|
|||||||
the global `triton.ClientConfig` struct into the client's constructor function.
|
the global `triton.ClientConfig` struct into the client's constructor function.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
config := &triton.ClientConfig{
|
config := &triton.ClientConfig{
|
||||||
TritonURL: os.Getenv("SDC_URL"),
|
TritonURL: os.Getenv("TRITON_URL"),
|
||||||
MantaURL: os.Getenv("MANTA_URL"),
|
MantaURL: os.Getenv("MANTA_URL"),
|
||||||
AccountName: accountName,
|
AccountName: accountName,
|
||||||
Signers: []authentication.Signer{sshKeySigner},
|
Username: os.Getenv("TRITON_USER"),
|
||||||
}
|
Signers: []authentication.Signer{sshKeySigner},
|
||||||
|
}
|
||||||
|
|
||||||
c, err := compute.NewClient(config)
|
c, err := compute.NewClient(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("compute.NewClient: %s", err)
|
log.Fatalf("compute.NewClient: %s", err)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Constructing `compute.Client` returns an interface which exposes `compute` API
|
Constructing `compute.Client` returns an interface which exposes `compute` API
|
||||||
@ -57,10 +64,10 @@ The same `triton.ClientConfig` will initialize the Manta `storage` client as
|
|||||||
well...
|
well...
|
||||||
|
|
||||||
```go
|
```go
|
||||||
c, err := storage.NewClient(config)
|
c, err := storage.NewClient(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("storage.NewClient: %s", err)
|
log.Fatalf("storage.NewClient: %s", err)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Error Handling
|
## Error Handling
|
||||||
@ -81,13 +88,14 @@ set:
|
|||||||
|
|
||||||
- `TRITON_TEST` - must be set to any value in order to indicate desire to create
|
- `TRITON_TEST` - must be set to any value in order to indicate desire to create
|
||||||
resources
|
resources
|
||||||
- `SDC_URL` - the base endpoint for the Triton API
|
- `TRITON_URL` - the base endpoint for the Triton API
|
||||||
- `SDC_ACCOUNT` - the account name for the Triton API
|
- `TRITON_ACCOUNT` - the account name for the Triton API
|
||||||
- `SDC_KEY_ID` - the fingerprint of the SSH key identifying the key
|
- `TRITON_KEY_ID` - the fingerprint of the SSH key identifying the key
|
||||||
|
|
||||||
Additionally, you may set `SDC_KEY_MATERIAL` to the contents of an unencrypted
|
Additionally, you may set `TRITON_KEY_MATERIAL` to the contents of an unencrypted
|
||||||
private key. If this is set, the PrivateKeySigner (see above) will be used - if
|
private key. If this is set, the PrivateKeySigner (see above) will be used - if
|
||||||
not the SSHAgentSigner will be used.
|
not the SSHAgentSigner will be used. You can also set `TRITON_USER` to run the tests
|
||||||
|
against an account other than the main Triton account
|
||||||
|
|
||||||
### Example Run
|
### Example Run
|
||||||
|
|
||||||
@ -96,9 +104,9 @@ The verbose output has been removed for brevity here.
|
|||||||
```
|
```
|
||||||
$ HTTP_PROXY=http://localhost:8888 \
|
$ HTTP_PROXY=http://localhost:8888 \
|
||||||
TRITON_TEST=1 \
|
TRITON_TEST=1 \
|
||||||
SDC_URL=https://us-sw-1.api.joyent.com \
|
TRITON_URL=https://us-sw-1.api.joyent.com \
|
||||||
SDC_ACCOUNT=AccountName \
|
TRITON_ACCOUNT=AccountName \
|
||||||
SDC_KEY_ID=a4:c6:f3:75:80:27:e0:03:a9:98:79:ef:c5:0a:06:11 \
|
TRITON_KEY_ID=a4:c6:f3:75:80:27:e0:03:a9:98:79:ef:c5:0a:06:11 \
|
||||||
go test -v -run "TestAccKey"
|
go test -v -run "TestAccKey"
|
||||||
=== RUN TestAccKey_Create
|
=== RUN TestAccKey_Create
|
||||||
--- PASS: TestAccKey_Create (12.46s)
|
--- PASS: TestAccKey_Create (12.46s)
|
||||||
@ -118,7 +126,7 @@ referencing your SSH key file use by your active `triton` CLI profile.
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ eval "$(triton env us-sw-1)"
|
$ eval "$(triton env us-sw-1)"
|
||||||
$ SDC_KEY_FILE=~/.ssh/triton-id_rsa go run examples/compute/instances.go
|
$ TRITON_KEY_FILE=~/.ssh/triton-id_rsa go run examples/compute/instances.go
|
||||||
```
|
```
|
||||||
|
|
||||||
The following is a complete example of how to initialize the `compute` package
|
The following is a complete example of how to initialize the `compute` package
|
||||||
@ -144,15 +152,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
keyID := os.Getenv("SDC_KEY_ID")
|
keyID := os.Getenv("TRITON_KEY_ID")
|
||||||
accountName := os.Getenv("SDC_ACCOUNT")
|
accountName := os.Getenv("TRITON_ACCOUNT")
|
||||||
keyMaterial := os.Getenv("SDC_KEY_MATERIAL")
|
keyMaterial := os.Getenv("TRITON_KEY_MATERIAL")
|
||||||
|
userName := os.Getenv("TRITON_USER")
|
||||||
|
|
||||||
var signer authentication.Signer
|
var signer authentication.Signer
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if keyMaterial == "" {
|
if keyMaterial == "" {
|
||||||
signer, err = authentication.NewSSHAgentSigner(keyID, accountName)
|
input := authentication.SSHAgentSignerInput{
|
||||||
|
KeyID: keyID,
|
||||||
|
AccountName: accountName,
|
||||||
|
Username: userName,
|
||||||
|
}
|
||||||
|
signer, err = authentication.NewSSHAgentSigner(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error Creating SSH Agent Signer: {{err}}", err)
|
log.Fatalf("Error Creating SSH Agent Signer: {{err}}", err)
|
||||||
}
|
}
|
||||||
@ -180,15 +194,22 @@ func main() {
|
|||||||
keyBytes = []byte(keyMaterial)
|
keyBytes = []byte(keyMaterial)
|
||||||
}
|
}
|
||||||
|
|
||||||
signer, err = authentication.NewPrivateKeySigner(keyID, []byte(keyMaterial), accountName)
|
input := authentication.PrivateKeySignerInput{
|
||||||
|
KeyID: keyID,
|
||||||
|
PrivateKeyMaterial: keyBytes,
|
||||||
|
AccountName: accountName,
|
||||||
|
Username: userName,
|
||||||
|
}
|
||||||
|
signer, err = authentication.NewPrivateKeySigner(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error Creating SSH Private Key Signer: {{err}}", err)
|
log.Fatalf("Error Creating SSH Private Key Signer: {{err}}", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &triton.ClientConfig{
|
config := &triton.ClientConfig{
|
||||||
TritonURL: os.Getenv("SDC_URL"),
|
TritonURL: os.Getenv("TRITON_URL"),
|
||||||
AccountName: accountName,
|
AccountName: accountName,
|
||||||
|
Username: userName,
|
||||||
Signers: []authentication.Signer{signer},
|
Signers: []authentication.Signer{signer},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
vendor/github.com/joyent/triton-go/authentication/private_key_signer.go
generated
vendored
31
vendor/github.com/joyent/triton-go/authentication/private_key_signer.go
generated
vendored
@ -9,6 +9,7 @@ import (
|
|||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/errwrap"
|
"github.com/hashicorp/errwrap"
|
||||||
@ -20,15 +21,23 @@ type PrivateKeySigner struct {
|
|||||||
keyFingerprint string
|
keyFingerprint string
|
||||||
algorithm string
|
algorithm string
|
||||||
accountName string
|
accountName string
|
||||||
|
userName string
|
||||||
hashFunc crypto.Hash
|
hashFunc crypto.Hash
|
||||||
|
|
||||||
privateKey *rsa.PrivateKey
|
privateKey *rsa.PrivateKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPrivateKeySigner(keyFingerprint string, privateKeyMaterial []byte, accountName string) (*PrivateKeySigner, error) {
|
type PrivateKeySignerInput struct {
|
||||||
keyFingerprintMD5 := strings.Replace(keyFingerprint, ":", "", -1)
|
KeyID string
|
||||||
|
PrivateKeyMaterial []byte
|
||||||
|
AccountName string
|
||||||
|
Username string
|
||||||
|
}
|
||||||
|
|
||||||
block, _ := pem.Decode(privateKeyMaterial)
|
func NewPrivateKeySigner(input PrivateKeySignerInput) (*PrivateKeySigner, error) {
|
||||||
|
keyFingerprintMD5 := strings.Replace(input.KeyID, ":", "", -1)
|
||||||
|
|
||||||
|
block, _ := pem.Decode(input.PrivateKeyMaterial)
|
||||||
if block == nil {
|
if block == nil {
|
||||||
return nil, errors.New("Error PEM-decoding private key material: nil block received")
|
return nil, errors.New("Error PEM-decoding private key material: nil block received")
|
||||||
}
|
}
|
||||||
@ -51,13 +60,17 @@ func NewPrivateKeySigner(keyFingerprint string, privateKeyMaterial []byte, accou
|
|||||||
|
|
||||||
signer := &PrivateKeySigner{
|
signer := &PrivateKeySigner{
|
||||||
formattedKeyFingerprint: displayKeyFingerprint,
|
formattedKeyFingerprint: displayKeyFingerprint,
|
||||||
keyFingerprint: keyFingerprint,
|
keyFingerprint: input.KeyID,
|
||||||
accountName: accountName,
|
accountName: input.AccountName,
|
||||||
|
|
||||||
hashFunc: crypto.SHA1,
|
hashFunc: crypto.SHA1,
|
||||||
privateKey: rsakey,
|
privateKey: rsakey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if input.Username != "" {
|
||||||
|
signer.userName = input.Username
|
||||||
|
}
|
||||||
|
|
||||||
_, algorithm, err := signer.SignRaw("HelloWorld")
|
_, algorithm, err := signer.SignRaw("HelloWorld")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Cannot sign using ssh agent: %s", err)
|
return nil, fmt.Errorf("Cannot sign using ssh agent: %s", err)
|
||||||
@ -80,7 +93,13 @@ func (s *PrivateKeySigner) Sign(dateHeader string) (string, error) {
|
|||||||
}
|
}
|
||||||
signedBase64 := base64.StdEncoding.EncodeToString(signed)
|
signedBase64 := base64.StdEncoding.EncodeToString(signed)
|
||||||
|
|
||||||
keyID := fmt.Sprintf("/%s/keys/%s", s.accountName, s.formattedKeyFingerprint)
|
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)
|
||||||
|
}
|
||||||
return fmt.Sprintf(authorizationHeaderFormat, keyID, "rsa-sha1", headerName, signedBase64), nil
|
return fmt.Sprintf(authorizationHeaderFormat, keyID, "rsa-sha1", headerName, signedBase64), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
21
vendor/github.com/joyent/triton-go/authentication/ssh_agent_signer.go
generated
vendored
21
vendor/github.com/joyent/triton-go/authentication/ssh_agent_signer.go
generated
vendored
@ -8,6 +8,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/errwrap"
|
"github.com/hashicorp/errwrap"
|
||||||
@ -24,13 +25,20 @@ type SSHAgentSigner struct {
|
|||||||
keyFingerprint string
|
keyFingerprint string
|
||||||
algorithm string
|
algorithm string
|
||||||
accountName string
|
accountName string
|
||||||
|
userName string
|
||||||
keyIdentifier string
|
keyIdentifier string
|
||||||
|
|
||||||
agent agent.Agent
|
agent agent.Agent
|
||||||
key ssh.PublicKey
|
key ssh.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSSHAgentSigner(keyFingerprint, accountName string) (*SSHAgentSigner, error) {
|
type SSHAgentSignerInput struct {
|
||||||
|
KeyID string
|
||||||
|
AccountName string
|
||||||
|
Username string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSSHAgentSigner(input SSHAgentSignerInput) (*SSHAgentSigner, error) {
|
||||||
sshAgentAddress, agentOk := os.LookupEnv("SSH_AUTH_SOCK")
|
sshAgentAddress, agentOk := os.LookupEnv("SSH_AUTH_SOCK")
|
||||||
if !agentOk {
|
if !agentOk {
|
||||||
return nil, ErrUnsetEnvVar
|
return nil, ErrUnsetEnvVar
|
||||||
@ -44,8 +52,8 @@ func NewSSHAgentSigner(keyFingerprint, accountName string) (*SSHAgentSigner, err
|
|||||||
ag := agent.NewClient(conn)
|
ag := agent.NewClient(conn)
|
||||||
|
|
||||||
signer := &SSHAgentSigner{
|
signer := &SSHAgentSigner{
|
||||||
keyFingerprint: keyFingerprint,
|
keyFingerprint: input.KeyID,
|
||||||
accountName: accountName,
|
accountName: input.AccountName,
|
||||||
agent: ag,
|
agent: ag,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +63,12 @@ func NewSSHAgentSigner(keyFingerprint, accountName string) (*SSHAgentSigner, err
|
|||||||
}
|
}
|
||||||
signer.key = matchingKey
|
signer.key = matchingKey
|
||||||
signer.formattedKeyFingerprint = formatPublicKeyFingerprint(signer.key, true)
|
signer.formattedKeyFingerprint = formatPublicKeyFingerprint(signer.key, true)
|
||||||
signer.keyIdentifier = fmt.Sprintf("/%s/keys/%s", signer.accountName, signer.formattedKeyFingerprint)
|
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")
|
_, algorithm, err := signer.SignRaw("HelloWorld")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
37
vendor/github.com/joyent/triton-go/client/client.go
generated
vendored
37
vendor/github.com/joyent/triton-go/client/client.go
generated
vendored
@ -21,7 +21,7 @@ import (
|
|||||||
const nilContext = "nil context"
|
const nilContext = "nil context"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrDefaultAuth = errors.New("default SSH agent authentication requires SDC_KEY_ID and SSH_AUTH_SOCK")
|
ErrDefaultAuth = errors.New("default SSH agent authentication requires SDC_KEY_ID / TRITON_KEY_ID and SSH_AUTH_SOCK")
|
||||||
ErrAccountName = errors.New("missing account name for Triton/Manta")
|
ErrAccountName = errors.New("missing account name for Triton/Manta")
|
||||||
ErrMissingURL = errors.New("missing Triton and/or Manta URL")
|
ErrMissingURL = errors.New("missing Triton and/or Manta URL")
|
||||||
|
|
||||||
@ -36,6 +36,7 @@ type Client struct {
|
|||||||
TritonURL url.URL
|
TritonURL url.URL
|
||||||
MantaURL url.URL
|
MantaURL url.URL
|
||||||
AccountName string
|
AccountName string
|
||||||
|
Username string
|
||||||
}
|
}
|
||||||
|
|
||||||
// New is used to construct a Client in order to make API
|
// New is used to construct a Client in order to make API
|
||||||
@ -81,7 +82,7 @@ func New(tritonURL string, mantaURL string, accountName string, signers ...authe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Default to constructing an SSHAgentSigner if there are no other signers
|
// Default to constructing an SSHAgentSigner if there are no other signers
|
||||||
// passed into NewClient and there's an SDC_KEY_ID and SSH_AUTH_SOCK
|
// passed into NewClient and there's an TRITON_KEY_ID and SSH_AUTH_SOCK
|
||||||
// available in the user's environ(7).
|
// available in the user's environ(7).
|
||||||
if len(newClient.Authorizers) == 0 {
|
if len(newClient.Authorizers) == 0 {
|
||||||
if err := newClient.DefaultAuth(); err != nil {
|
if err := newClient.DefaultAuth(); err != nil {
|
||||||
@ -92,21 +93,43 @@ func New(tritonURL string, mantaURL string, accountName string, signers ...authe
|
|||||||
return newClient, nil
|
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
|
// 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
|
// 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
|
// 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.
|
// user's environ(7). If so we default to the SSH agent key signer.
|
||||||
func (c *Client) DefaultAuth() error {
|
func (c *Client) DefaultAuth() error {
|
||||||
if keyID, keyOk := os.LookupEnv("SDC_KEY_ID"); keyOk {
|
tritonKeyId := GetTritonEnv("KEY_ID")
|
||||||
defaultSigner, err := authentication.NewSSHAgentSigner(keyID, c.AccountName)
|
if tritonKeyId != "" {
|
||||||
|
input := authentication.SSHAgentSignerInput{
|
||||||
|
KeyID: tritonKeyId,
|
||||||
|
AccountName: c.AccountName,
|
||||||
|
Username: c.Username,
|
||||||
|
}
|
||||||
|
defaultSigner, err := authentication.NewSSHAgentSigner(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errwrap.Wrapf("problem initializing NewSSHAgentSigner: {{err}}", err)
|
return errwrap.Wrapf("problem initializing NewSSHAgentSigner: {{err}}", err)
|
||||||
}
|
}
|
||||||
c.Authorizers = append(c.Authorizers, defaultSigner)
|
c.Authorizers = append(c.Authorizers, defaultSigner)
|
||||||
} else {
|
|
||||||
return ErrDefaultAuth
|
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
return ErrDefaultAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsecureSkipTLSVerify turns off TLS verification for the client connection. This
|
// InsecureSkipTLSVerify turns off TLS verification for the client connection. This
|
||||||
|
1
vendor/github.com/joyent/triton-go/storage/objects.go
generated
vendored
1
vendor/github.com/joyent/triton-go/storage/objects.go
generated
vendored
@ -260,7 +260,6 @@ func (s *ObjectsClient) Put(ctx context.Context, input *PutObjectInput) error {
|
|||||||
absPath := absFileInput(s.client.AccountName, input.ObjectPath)
|
absPath := absFileInput(s.client.AccountName, input.ObjectPath)
|
||||||
|
|
||||||
if input.ForceInsert {
|
if input.ForceInsert {
|
||||||
// IsDir() uses a path relative to the account
|
|
||||||
absDirName := _AbsCleanPath(path.Dir(string(absPath)))
|
absDirName := _AbsCleanPath(path.Dir(string(absPath)))
|
||||||
exists, err := checkDirectoryTreeExists(*s, ctx, absDirName)
|
exists, err := checkDirectoryTreeExists(*s, ctx, absDirName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
1
vendor/github.com/joyent/triton-go/triton.go
generated
vendored
1
vendor/github.com/joyent/triton-go/triton.go
generated
vendored
@ -14,5 +14,6 @@ type ClientConfig struct {
|
|||||||
TritonURL string
|
TritonURL string
|
||||||
MantaURL string
|
MantaURL string
|
||||||
AccountName string
|
AccountName string
|
||||||
|
Username string
|
||||||
Signers []authentication.Signer
|
Signers []authentication.Signer
|
||||||
}
|
}
|
||||||
|
24
vendor/vendor.json
vendored
24
vendor/vendor.json
vendored
@ -292,28 +292,28 @@
|
|||||||
"revisionTime": "2016-01-12T19:33:35Z"
|
"revisionTime": "2016-01-12T19:33:35Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "NYs0qvjZwsMZAXMtg2HRiED2cb4=",
|
"checksumSHA1": "oINoQSRkPinChzwEHr3VatB9++Y=",
|
||||||
"path": "github.com/joyent/triton-go",
|
"path": "github.com/joyent/triton-go",
|
||||||
"revision": "8365851ee7afcbb4cc1c7ba2e414b242ce0574f1",
|
"revision": "86ba9699869b6cd5ea3290faad7be659efc7d6ce",
|
||||||
"revisionTime": "2017-12-15T19:09:06Z"
|
"revisionTime": "2017-12-28T20:20:46Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "Cth7NCLH/HaeKh9ZMRpQtudTEQQ=",
|
"checksumSHA1": "d6pxw8DLxYehLr92fWZTLEWVws8=",
|
||||||
"path": "github.com/joyent/triton-go/authentication",
|
"path": "github.com/joyent/triton-go/authentication",
|
||||||
"revision": "8365851ee7afcbb4cc1c7ba2e414b242ce0574f1",
|
"revision": "86ba9699869b6cd5ea3290faad7be659efc7d6ce",
|
||||||
"revisionTime": "2017-12-15T19:09:06Z"
|
"revisionTime": "2017-12-28T20:20:46Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "3ju04DVaxotpCKBF3Q/0vCSOlec=",
|
"checksumSHA1": "GCHfn8d1Mhswm7n7IRnT0n/w+dw=",
|
||||||
"path": "github.com/joyent/triton-go/client",
|
"path": "github.com/joyent/triton-go/client",
|
||||||
"revision": "8365851ee7afcbb4cc1c7ba2e414b242ce0574f1",
|
"revision": "86ba9699869b6cd5ea3290faad7be659efc7d6ce",
|
||||||
"revisionTime": "2017-12-15T19:09:06Z"
|
"revisionTime": "2017-12-28T20:20:46Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "/WtyDZMgstGbBYtQ0f+ZfKMS4v8=",
|
"checksumSHA1": "PJe3Rs8H466xR8o5audO8oWk44Q=",
|
||||||
"path": "github.com/joyent/triton-go/storage",
|
"path": "github.com/joyent/triton-go/storage",
|
||||||
"revision": "8365851ee7afcbb4cc1c7ba2e414b242ce0574f1",
|
"revision": "86ba9699869b6cd5ea3290faad7be659efc7d6ce",
|
||||||
"revisionTime": "2017-12-15T19:09:06Z"
|
"revisionTime": "2017-12-28T20:20:46Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "github.com/klauspost/cpuid",
|
"path": "github.com/klauspost/cpuid",
|
||||||
|
Loading…
Reference in New Issue
Block a user