Unverified Commit 2d33b898 by Shuwei Hao Committed by GitHub

Merge pull request #37 from haoshuwei/feat/support-aliyun-ramrole

support to init client using ramrole
parents bde19540 3740773b
package main
import (
"encoding/json"
"fmt"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"github.com/joho/godotenv"
"github.com/pkg/errors"
"io/ioutil"
"net/http"
"os"
"time"
)
const (
......@@ -24,6 +27,16 @@ const (
networkTypeInternal = "internal"
)
// RoleAuth define STS Token Response
type RoleAuth struct {
AccessKeyID string
AccessKeySecret string
Expiration time.Time
SecurityToken string
LastUpdated time.Time
Code string
}
// load environment vars from $ALIBABA_CLOUD_CREDENTIALS_FILE, if it exists
func loadEnv() error {
envFile := os.Getenv("ALIBABA_CLOUD_CREDENTIALS_FILE")
......@@ -107,3 +120,62 @@ func getEcsRegionID(config map[string]string) string {
return value
}
}
// getRamRole return ramrole name
func getRamRole () (string, error) {
subpath := "ram/security-credentials/"
roleName, err := GetMetaData(subpath)
if err != nil {
return "", err
}
return roleName, nil
}
//getSTSAK return AccessKeyID, AccessKeySecret and SecurityToken
func getSTSAK(ramrole string) (string, string, string, error) {
// AliyunCSVeleroRole
roleAuth := RoleAuth{}
ramRoleURL := fmt.Sprintf("ram/security-credentials/%s", ramrole)
roleInfo, err := GetMetaData(ramRoleURL)
if err != nil {
return "", "", "", err
}
err = json.Unmarshal([]byte(roleInfo), &roleAuth)
if err != nil {
return "", "", "", err
}
return roleAuth.AccessKeyID, roleAuth.AccessKeySecret, roleAuth.SecurityToken, nil
}
//GetMetaData get metadata from ecs meta-server
func GetMetaData(resource string) (string, error) {
resp, err := http.Get(metadataURL + resource)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(body), nil
}
func updateOssClient(ramRole string, endpoint string, client bucketGetter) (bucketGetter, error) {
bucketGetter := &ossBucketGetter{}
if len(ramRole) == 0 {
return client, nil
}
accessKeyID, accessKeySecret, stsToken, err := getSTSAK(ramRole)
if err != nil {
return nil, err
}
ossClient, err := oss.New(endpoint, accessKeyID, accessKeySecret, oss.SecurityToken(stsToken))
if err != nil {
return nil, err
}
bucketGetter.client = ossClient
return bucketGetter, err
}
......@@ -68,6 +68,8 @@ type ObjectStore struct {
client bucketGetter
encryptionKeyID string
privateKey []byte
ramRole string
endpoint string
}
// newObjectStore init ObjectStore
......@@ -76,6 +78,11 @@ func newObjectStore(logger logrus.FieldLogger) *ObjectStore {
}
func (o *ObjectStore) getBucket(bucket string) (ossBucket, error) {
var err error
o.client, err = updateOssClient(o.ramRole, o. endpoint, o.client)
if err != nil {
o.log.Errorf("failed to update OSS Client: %v", err)
}
bucketObj, err := o.client.Bucket(bucket)
if err != nil {
o.log.Errorf("failed to get OSS bucket: %v", err)
......@@ -89,31 +96,62 @@ func (o *ObjectStore) Init(config map[string]string) error {
return err
}
if err := loadEnv(); err != nil {
return err
}
accessKeyID := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
accessKeySecret := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
stsToken := os.Getenv("ALIBABA_CLOUD_ACCESS_STS_TOKEN")
encryptionKeyID := os.Getenv("ALIBABA_CLOUD_ENCRYPTION_KEY_ID")
if len(accessKeyID) == 0 {
return errors.Errorf("ALIBABA_CLOUD_ACCESS_KEY_ID environment variable is not set")
}
if len(accessKeySecret) == 0 {
return errors.Errorf("ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variable is not set")
}
accessKeyID := ""
accessKeySecret := ""
stsToken := ""
encryptionKeyID := ""
endpoint := getOssEndpoint(config)
var client *oss.Client
var err error
if len(stsToken) == 0 {
client, err = oss.New(endpoint, accessKeyID, accessKeySecret)
endpoint := getOssEndpoint(config)
veleroForAck := os.Getenv("VELERO_FOR_ACK")
isHybrid := os.Getenv("IS_HYBRID")
if veleroForAck == "true" {
if isHybrid == "true" {
accessKeyID = os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
accessKeySecret = os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
if len(accessKeyID) == 0 {
return errors.Errorf("IS_HYBRID set to true, but ALIBABA_CLOUD_ACCESS_KEY_ID environment variable is not set")
}
if len(accessKeySecret) == 0 {
return errors.Errorf("IS_HYBRID set to true, but ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variable is not set")
}
} else {
ramRole, err := getRamRole()
if err != nil {
return errors.Errorf("Failed to get ram role with err: %v", err)
}
o.ramRole = ramRole
accessKeyID, accessKeySecret, stsToken, err = getSTSAK(ramRole)
if err != nil {
return errors.Errorf("Failed to get sts token from ram role %s with err: %v", ramRole, err)
}
client, err = oss.New(endpoint, accessKeyID, accessKeySecret, oss.SecurityToken(stsToken))
}
} else {
client, err = oss.New(endpoint, accessKeyID, accessKeySecret, oss.SecurityToken(stsToken))
if err := loadEnv(); err != nil {
return err
}
accessKeyID = os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
accessKeySecret = os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
stsToken = os.Getenv("ALIBABA_CLOUD_ACCESS_STS_TOKEN")
encryptionKeyID = os.Getenv("ALIBABA_CLOUD_ENCRYPTION_KEY_ID")
if len(accessKeyID) == 0 {
return errors.Errorf("ALIBABA_CLOUD_ACCESS_KEY_ID environment variable is not set")
}
if len(accessKeySecret) == 0 {
return errors.Errorf("ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variable is not set")
}
if len(stsToken) == 0 {
client, err = oss.New(endpoint, accessKeyID, accessKeySecret)
} else {
client, err = oss.New(endpoint, accessKeyID, accessKeySecret, oss.SecurityToken(stsToken))
}
}
if err != nil {
......@@ -124,6 +162,7 @@ func (o *ObjectStore) Init(config map[string]string) error {
client,
}
o.endpoint = endpoint
o.encryptionKeyID = encryptionKeyID
return nil
......@@ -140,7 +179,6 @@ func (o *ObjectStore) PutObject(bucket, key string, body io.Reader) error {
oss.ServerSideEncryption("KMS"),
oss.ServerSideEncryptionKeyID(o.encryptionKeyID))
} else {
err = bucketObj.PutObject(key, body)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment