vendor: add qingstor-sdk-go for QingStor

This commit is contained in:
wuyu
2017-08-04 17:09:28 +01:00
committed by Nick Craig-Wood
parent f682002b84
commit 466dd22b44
136 changed files with 15952 additions and 1 deletions
+172
View File
@@ -0,0 +1,172 @@
// +-------------------------------------------------------------------------
// | Copyright (C) 2016 Yunify, Inc.
// +-------------------------------------------------------------------------
// | Licensed under the Apache License, Version 2.0 (the "License");
// | you may not use this work except in compliance with the License.
// | You may obtain a copy of the License in the LICENSE file, or at:
// |
// | http://www.apache.org/licenses/LICENSE-2.0
// |
// | Unless required by applicable law or agreed to in writing, software
// | distributed under the License is distributed on an "AS IS" BASIS,
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// | See the License for the specific language governing permissions and
// | limitations under the License.
// +-------------------------------------------------------------------------
package config
import (
"errors"
"io/ioutil"
"net/http"
"os"
"strings"
"github.com/pengsrc/go-shared/yaml"
"github.com/yunify/qingstor-sdk-go/logger"
)
// A Config stores a configuration of this sdk.
type Config struct {
AccessKeyID string `yaml:"access_key_id"`
SecretAccessKey string `yaml:"secret_access_key"`
Host string `yaml:"host"`
Port int `yaml:"port"`
Protocol string `yaml:"protocol"`
ConnectionRetries int `yaml:"connection_retries"`
AdditionalUserAgent string `yaml:"additional_user_agent"`
LogLevel string `yaml:"log_level"`
Connection *http.Client
}
// New create a Config with given AccessKeyID and SecretAccessKey.
func New(accessKeyID, secretAccessKey string) (*Config, error) {
config, err := NewDefault()
if err != nil {
return nil, err
}
config.AccessKeyID = accessKeyID
config.SecretAccessKey = secretAccessKey
config.Connection = &http.Client{}
return config, nil
}
// NewDefault create a Config with default configuration.
func NewDefault() (*Config, error) {
config := &Config{}
err := config.LoadDefaultConfig()
if err != nil {
return nil, err
}
config.Connection = &http.Client{}
return config, nil
}
// Check checks the configuration.
func (c *Config) Check() error {
if c.AccessKeyID == "" {
return errors.New("access key ID not specified")
}
if c.SecretAccessKey == "" {
return errors.New("secret access key not specified")
}
if c.Host == "" {
return errors.New("server host not specified")
}
if c.Port <= 0 {
return errors.New("server port not specified")
}
if c.Protocol == "" {
return errors.New("server protocol not specified")
}
if c.AdditionalUserAgent != "" {
for _, x := range c.AdditionalUserAgent {
// Allow space(32) to ~(126) in ASCII Table, exclude "(34).
if int(x) < 32 || int(x) > 126 || int(x) == 32 || int(x) == 34 {
return errors.New("additional User-Agent contains characters that not allowed")
}
}
}
err := logger.CheckLevel(c.LogLevel)
if err != nil {
return err
}
return nil
}
// LoadDefaultConfig loads the default configuration for Config.
// It returns error if yaml decode failed.
func (c *Config) LoadDefaultConfig() error {
_, err := yaml.Decode([]byte(DefaultConfigFileContent), c)
if err != nil {
logger.Error("Config parse error: " + err.Error())
return err
}
logger.SetLevel(c.LogLevel)
return nil
}
// LoadUserConfig loads user configuration in ~/.qingstor/config.yaml for Config.
// It returns error if file not found.
func (c *Config) LoadUserConfig() error {
_, err := os.Stat(GetUserConfigFilePath())
if err != nil {
logger.Warn("Installing default config file to \"" + GetUserConfigFilePath() + "\"")
InstallDefaultUserConfig()
}
return c.LoadConfigFromFilePath(GetUserConfigFilePath())
}
// LoadConfigFromFilePath loads configuration from a specified local path.
// It returns error if file not found or yaml decode failed.
func (c *Config) LoadConfigFromFilePath(filepath string) error {
if strings.Index(filepath, "~/") == 0 {
filepath = strings.Replace(filepath, "~/", getHome()+"/", 1)
}
yamlString, err := ioutil.ReadFile(filepath)
if err != nil {
logger.Error("File not found: " + filepath)
return err
}
return c.LoadConfigFromContent(yamlString)
}
// LoadConfigFromContent loads configuration from a given byte slice.
// It returns error if yaml decode failed.
func (c *Config) LoadConfigFromContent(content []byte) error {
c.LoadDefaultConfig()
_, err := yaml.Decode(content, c)
if err != nil {
logger.Error("Config parse error: " + err.Error())
return err
}
err = c.Check()
if err != nil {
return err
}
logger.SetLevel(c.LogLevel)
return nil
}
+108
View File
@@ -0,0 +1,108 @@
// +-------------------------------------------------------------------------
// | Copyright (C) 2016 Yunify, Inc.
// +-------------------------------------------------------------------------
// | Licensed under the Apache License, Version 2.0 (the "License");
// | you may not use this work except in compliance with the License.
// | You may obtain a copy of the License in the LICENSE file, or at:
// |
// | http://www.apache.org/licenses/LICENSE-2.0
// |
// | Unless required by applicable law or agreed to in writing, software
// | distributed under the License is distributed on an "AS IS" BASIS,
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// | See the License for the specific language governing permissions and
// | limitations under the License.
// +-------------------------------------------------------------------------
package config
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/yunify/qingstor-sdk-go/logger"
)
func TestConfig(t *testing.T) {
c := Config{
AccessKeyID: "AccessKeyID",
SecretAccessKey: "SecretAccessKey",
Host: "qingstor.dev",
Port: 443,
Protocol: "https",
ConnectionRetries: 10,
LogLevel: "warn",
}
assert.Equal(t, "AccessKeyID", c.AccessKeyID)
assert.Equal(t, "SecretAccessKey", c.SecretAccessKey)
assert.Equal(t, "qingstor.dev", c.Host)
assert.Equal(t, 10, c.ConnectionRetries)
assert.Equal(t, "warn", c.LogLevel)
c.AdditionalUserAgent = `"`
assert.Error(t, c.Check())
c.AdditionalUserAgent = `test/user`
assert.NoError(t, c.Check())
}
func TestLoadDefaultConfig(t *testing.T) {
config := Config{}
config.LoadDefaultConfig()
assert.Equal(t, "", config.AccessKeyID)
assert.Equal(t, "", config.SecretAccessKey)
assert.Equal(t, "https", config.Protocol)
assert.Equal(t, "qingstor.com", config.Host)
assert.Equal(t, "", config.AdditionalUserAgent)
assert.Equal(t, "warning", logger.GetLevel())
}
func TestLoadUserConfig(t *testing.T) {
config := Config{}
config.LoadUserConfig()
assert.NotNil(t, config.Host)
assert.NotNil(t, config.Protocol)
}
func TestLoadConfigFromContent(t *testing.T) {
fileContent := `
access_key_id: 'access_key_id'
secret_access_key: 'secret_access_key'
log_level: 'debug'
`
config := Config{}
config.LoadConfigFromContent([]byte(fileContent))
assert.Equal(t, "access_key_id", config.AccessKeyID)
assert.Equal(t, "secret_access_key", config.SecretAccessKey)
assert.Equal(t, "https", config.Protocol)
assert.Equal(t, "qingstor.com", config.Host)
assert.Equal(t, "debug", logger.GetLevel())
}
func TestNewDefault(t *testing.T) {
config, err := NewDefault()
assert.Nil(t, err)
assert.Equal(t, "", config.AccessKeyID)
assert.Equal(t, "", config.SecretAccessKey)
assert.Equal(t, "https", config.Protocol)
assert.Equal(t, "qingstor.com", config.Host)
assert.Equal(t, 3, config.ConnectionRetries)
}
func TestNew(t *testing.T) {
config, err := New("AccessKeyID", "SecretAccessKey")
assert.Nil(t, err)
assert.Equal(t, "AccessKeyID", config.AccessKeyID)
assert.Equal(t, "SecretAccessKey", config.SecretAccessKey)
assert.Equal(t, "https", config.Protocol)
assert.Equal(t, "qingstor.com", config.Host)
}
+74
View File
@@ -0,0 +1,74 @@
// +-------------------------------------------------------------------------
// | Copyright (C) 2016 Yunify, Inc.
// +-------------------------------------------------------------------------
// | Licensed under the Apache License, Version 2.0 (the "License");
// | you may not use this work except in compliance with the License.
// | You may obtain a copy of the License in the LICENSE file, or at:
// |
// | http://www.apache.org/licenses/LICENSE-2.0
// |
// | Unless required by applicable law or agreed to in writing, software
// | distributed under the License is distributed on an "AS IS" BASIS,
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// | See the License for the specific language governing permissions and
// | limitations under the License.
// +-------------------------------------------------------------------------
package config
import (
"io/ioutil"
"os"
"path"
"runtime"
"strings"
)
// DefaultConfigFileContent is the content of default config file.
const DefaultConfigFileContent = `# QingStor services configuration
#access_key_id: ACCESS_KEY_ID
#secret_access_key: SECRET_ACCESS_KEY
host: qingstor.com
port: 443
protocol: https
connection_retries: 3
# Additional User-Agent
additional_user_agent: ""
# Valid log levels are "debug", "info", "warn", "error", and "fatal".
log_level: warn
`
// DefaultConfigFile is the filename of default config file.
const DefaultConfigFile = "~/.qingstor/config.yaml"
// GetUserConfigFilePath returns the user config file path.
func GetUserConfigFilePath() string {
return strings.Replace(DefaultConfigFile, "~/", getHome()+"/", 1)
}
// InstallDefaultUserConfig will install default config file.
func InstallDefaultUserConfig() error {
err := os.MkdirAll(path.Dir(GetUserConfigFilePath()), 0755)
if err != nil {
return err
}
return ioutil.WriteFile(GetUserConfigFilePath(), []byte(DefaultConfigFileContent), 0644)
}
func getHome() string {
home := os.Getenv("HOME")
if runtime.GOOS == "windows" {
home = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
if home == "" {
home = os.Getenv("USERPROFILE")
}
}
return home
}