qingcloud-sdk 0.4.1 → 2.0.0.pre.alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +201 -21
  3. data/README.md +141 -61
  4. data/bin/console +3 -3
  5. data/lib/qingcloud/sdk.rb +16 -14
  6. data/lib/qingcloud/sdk/general/config.rb +70 -0
  7. data/lib/qingcloud/sdk/general/contract.rb +28 -17
  8. data/lib/qingcloud/sdk/general/default/config.yaml +13 -0
  9. data/lib/qingcloud/sdk/general/error.rb +41 -32
  10. data/lib/qingcloud/sdk/general/logger.rb +54 -0
  11. data/lib/qingcloud/sdk/request/preprocessor.rb +81 -0
  12. data/lib/qingcloud/sdk/request/request.rb +80 -0
  13. data/lib/qingcloud/sdk/request/signer.rb +53 -0
  14. data/lib/qingcloud/sdk/service/cache.rb +1005 -0
  15. data/lib/qingcloud/sdk/service/dns_alias.rb +150 -0
  16. data/lib/qingcloud/sdk/service/eip.rb +389 -0
  17. data/lib/qingcloud/sdk/service/image.rb +304 -0
  18. data/lib/qingcloud/sdk/service/instance.rb +585 -0
  19. data/lib/qingcloud/sdk/service/job.rb +71 -0
  20. data/lib/qingcloud/sdk/service/key_pair.rb +257 -0
  21. data/lib/qingcloud/sdk/service/load_balancer.rb +1119 -0
  22. data/lib/qingcloud/sdk/service/mongo.rb +566 -0
  23. data/lib/qingcloud/sdk/service/qingcloud.rb +185 -0
  24. data/lib/qingcloud/sdk/service/rdb.rb +751 -0
  25. data/lib/qingcloud/sdk/service/router.rb +778 -0
  26. data/lib/qingcloud/sdk/service/security_group.rb +645 -0
  27. data/lib/qingcloud/sdk/service/shared_storage.rb +666 -0
  28. data/lib/qingcloud/sdk/service/snapshot.rb +283 -0
  29. data/lib/qingcloud/sdk/service/tag.rb +227 -0
  30. data/lib/qingcloud/sdk/service/user_data.rb +61 -0
  31. data/lib/qingcloud/sdk/service/volume.rb +296 -0
  32. data/lib/qingcloud/sdk/service/vxnet.rb +295 -0
  33. data/lib/qingcloud/sdk/version.rb +19 -5
  34. metadata +98 -29
  35. data/.gitignore +0 -13
  36. data/.rspec +0 -2
  37. data/.travis.yml +0 -3
  38. data/Rakefile +0 -6
  39. data/lib/qingcloud/sdk/iaas/connector.rb +0 -99
  40. data/lib/qingcloud/sdk/iaas/foundation.rb +0 -73
  41. data/lib/qingcloud/sdk/iaas/service.rb +0 -1274
  42. data/lib/qingcloud/sdk/template/config.json +0 -4
  43. data/lib/qingcloud/sdk/utility/file_manager.rb +0 -43
  44. data/lib/qingcloud/sdk/utility/json_parser.rb +0 -41
  45. data/lib/qingcloud/sdk/utility/logger.rb +0 -19
  46. data/qingcloud-sdk.gemspec +0 -31
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "qingcloud/sdk"
3
+ require 'bundler/setup'
4
+ require 'qingcloud/sdk'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "qingcloud/sdk"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start
data/lib/qingcloud/sdk.rb CHANGED
@@ -1,15 +1,17 @@
1
- require 'qingcloud/sdk/version'
1
+ # +-------------------------------------------------------------------------
2
+ # | Copyright (C) 2016 Yunify, Inc.
3
+ # +-------------------------------------------------------------------------
4
+ # | Licensed under the Apache License, Version 2.0 (the "License");
5
+ # | you may not use this work except in compliance with the License.
6
+ # | You may obtain a copy of the License in the LICENSE file, or at:
7
+ # |
8
+ # | http://www.apache.org/licenses/LICENSE-2.0
9
+ # |
10
+ # | Unless required by applicable law or agreed to in writing, software
11
+ # | distributed under the License is distributed on an "AS IS" BASIS,
12
+ # | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # | See the License for the specific language governing permissions and
14
+ # | limitations under the License.
15
+ # +-------------------------------------------------------------------------
2
16
 
3
- # General
4
- require 'qingcloud/sdk/general/contract'
5
- require 'qingcloud/sdk/general/error'
6
-
7
- # Utility
8
- require 'qingcloud/sdk/utility/logger'
9
- require 'qingcloud/sdk/utility/file_manager'
10
- require 'qingcloud/sdk/utility/json_parser'
11
-
12
- # Client
13
- require 'qingcloud/sdk/iaas/connector'
14
- require 'qingcloud/sdk/iaas/foundation'
15
- require 'qingcloud/sdk/iaas/service'
17
+ Dir[File.dirname(__FILE__) + '/sdk/**/*.rb'].each { |file| require file }
@@ -0,0 +1,70 @@
1
+ # +-------------------------------------------------------------------------
2
+ # | Copyright (C) 2016 Yunify, Inc.
3
+ # +-------------------------------------------------------------------------
4
+ # | Licensed under the Apache License, Version 2.0 (the "License");
5
+ # | you may not use this work except in compliance with the License.
6
+ # | You may obtain a copy of the License in the LICENSE file, or at:
7
+ # |
8
+ # | http://www.apache.org/licenses/LICENSE-2.0
9
+ # |
10
+ # | Unless required by applicable law or agreed to in writing, software
11
+ # | distributed under the License is distributed on an "AS IS" BASIS,
12
+ # | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # | See the License for the specific language governing permissions and
14
+ # | limitations under the License.
15
+ # +-------------------------------------------------------------------------
16
+
17
+ require 'fileutils'
18
+ require 'yaml'
19
+
20
+ require 'active_support/core_ext/hash/keys'
21
+ require 'active_support/core_ext/hash/deep_merge'
22
+ require 'net/http/persistent'
23
+
24
+ module QingCloud
25
+ module SDK
26
+ class Config < Hash
27
+ attr_accessor :connection
28
+
29
+ def self.init(access_key_id, secret_access_key)
30
+ initial_config = {
31
+ qy_access_key_id: access_key_id,
32
+ qy_secret_access_key: secret_access_key,
33
+ }
34
+ Config.new(initial_config)
35
+ end
36
+
37
+ def initialize(initial_config = {})
38
+ self.connection = Net::HTTP::Persistent.new
39
+ load_default_config
40
+ update initial_config
41
+ end
42
+
43
+ def update(another_config = {})
44
+ deep_merge! another_config.deep_symbolize_keys!
45
+ Logger.set_level self[:log_level]
46
+ self
47
+ end
48
+
49
+ def load_default_config
50
+ load_config_from_file Contract::DEFAULT_CONFIG_FILEPATH
51
+ end
52
+
53
+ def load_user_config
54
+ install_default_user_config unless File.exist? Contract::USER_CONFIG_FILEPATH
55
+ load_config_from_file Contract::USER_CONFIG_FILEPATH
56
+ end
57
+
58
+ def load_config_from_file(path)
59
+ path = path.sub '~', Dir.home if path.start_with? '~/'
60
+ update YAML.load_file File.absolute_path path
61
+ end
62
+
63
+ def install_default_user_config
64
+ Logger.warn "Installing default config file to #{Contract::USER_CONFIG_FILEPATH}"
65
+ FileUtils.mkdir_p Contract::USER_SUPPORT_DIRECTORY
66
+ FileUtils.copy Contract::DEFAULT_CONFIG_FILEPATH, Contract::USER_CONFIG_FILEPATH
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,20 +1,31 @@
1
- module QingCloud
2
- module SDK
3
- module Contract
4
-
5
- SUPPORT_DIRECTORY = "#{Dir.home}/.qingcloud"
6
- CONFIG_FILE_NAME = 'config.json'
7
- CONFIG_FILE_PATH = "#{SUPPORT_DIRECTORY}/#{CONFIG_FILE_NAME}"
8
- LOG_FILE_NAME = 'access.log'
9
- LOG_FILE_PATH = "#{SUPPORT_DIRECTORY}/#{LOG_FILE_NAME}"
1
+ # +-------------------------------------------------------------------------
2
+ # | Copyright (C) 2016 Yunify, Inc.
3
+ # +-------------------------------------------------------------------------
4
+ # | Licensed under the Apache License, Version 2.0 (the "License");
5
+ # | you may not use this work except in compliance with the License.
6
+ # | You may obtain a copy of the License in the LICENSE file, or at:
7
+ # |
8
+ # | http://www.apache.org/licenses/LICENSE-2.0
9
+ # |
10
+ # | Unless required by applicable law or agreed to in writing, software
11
+ # | distributed under the License is distributed on an "AS IS" BASIS,
12
+ # | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # | See the License for the specific language governing permissions and
14
+ # | limitations under the License.
15
+ # +-------------------------------------------------------------------------
10
16
 
11
- TEMPLATE_DIRECTORY = Gem::Specification.find_by_name('qingcloud-sdk').gem_dir + '/lib/qingcloud/sdk/template'
12
- TEMPLATE_CONFIG_FILE_NAME = 'config.json'
13
- TEMPLATE_CONFIG_FILE_PATH = "#{TEMPLATE_DIRECTORY}/#{TEMPLATE_CONFIG_FILE_NAME}"
14
-
15
- API_URL = 'https://api.qingcloud.com'
16
- IaaS_API_URL = "#{API_URL}/iaas/?"
17
+ module QingCloud
18
+ module SDK
19
+ module Contract
20
+ USER_SUPPORT_DIRECTORY = "#{Dir.home}/.qingcloud".freeze
21
+ USER_CONFIG_FILENAME = 'config.yaml'.freeze
22
+ USER_CONFIG_FILEPATH = "#{USER_SUPPORT_DIRECTORY}/#{USER_CONFIG_FILENAME}".freeze
17
23
 
18
- end
24
+ # GEM_DIRECTORY = Gem::Specification.find_by_name('qingcloud-sdk').gem_dir
25
+ # DEFAULT_SUPPORT_DIRECTORY = GEM_DIRECTORY + '/lib/qingcloud/sdk/commons/default'
26
+ DEFAULT_SUPPORT_DIRECTORY = File.expand_path(File.dirname(__FILE__) + '/./default')
27
+ DEFAULT_CONFIG_FILENAME = 'config.yaml'.freeze
28
+ DEFAULT_CONFIG_FILEPATH = "#{DEFAULT_SUPPORT_DIRECTORY}/#{DEFAULT_CONFIG_FILENAME}".freeze
19
29
  end
20
- end
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ # QingCloud services configuration
2
+
3
+ #qy_access_key_id: 'ACCESS_KEY_ID'
4
+ #qy_secret_access_key: 'SECRET_ACCESS_KEY'
5
+
6
+ host: 'api.qingcloud.com'
7
+ port: 443
8
+ protocol: 'https'
9
+ uri: '/iaas'
10
+ connection_retries: 3
11
+
12
+ # Valid log levels are "debug", "info", "warn", "error", and "fatal".
13
+ log_level: 'warn'
@@ -1,39 +1,48 @@
1
- module QingCloud
2
- module SDK
3
- module Error
1
+ # +-------------------------------------------------------------------------
2
+ # | Copyright (C) 2016 Yunify, Inc.
3
+ # +-------------------------------------------------------------------------
4
+ # | Licensed under the Apache License, Version 2.0 (the "License");
5
+ # | you may not use this work except in compliance with the License.
6
+ # | You may obtain a copy of the License in the LICENSE file, or at:
7
+ # |
8
+ # | http://www.apache.org/licenses/LICENSE-2.0
9
+ # |
10
+ # | Unless required by applicable law or agreed to in writing, software
11
+ # | distributed under the License is distributed on an "AS IS" BASIS,
12
+ # | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # | See the License for the specific language governing permissions and
14
+ # | limitations under the License.
15
+ # +-------------------------------------------------------------------------
4
16
 
5
- class SDKError < StandardError
6
- end
17
+ module QingCloud
18
+ module SDK
19
+ class SDKError < StandardError
20
+ end
7
21
 
8
- class NetworkError < SDKError
9
- def message
10
- 'Network Error, please check your internet connection.'
11
- end
12
- end
22
+ class NetworkError < SDKError
23
+ end
13
24
 
14
- class ServerError < SDKError
15
- def initialize(code)
16
- super "Server Response with Error Code \"#{code}\"."
17
- end
18
- end
25
+ class ParameterRequiredError < SDKError
26
+ def initialize(parameter_name, parent_name)
27
+ @parameter_name = parameter_name
28
+ @parent_name = parent_name
29
+ end
19
30
 
20
- class ParameterError < SDKError
21
- def initialize(something)
22
- super "Parameter Error when \"#{something}\"."
23
- end
24
- end
31
+ def message
32
+ "\"#{@parameter_name}\" is required in \"#{@parent_name}\"."
33
+ end
34
+ end
25
35
 
26
- class APIError < SDKError
27
- def initialize(something)
28
- super "API Error: \"#{something}\"."
29
- end
30
- end
36
+ class ParameterValueNotAllowedError < SDKError
37
+ def initialize(parameter_name, parameter_value, allowed_values)
38
+ @parameter_name = parameter_name
39
+ @parameter_value = parameter_value
40
+ @allowed_values = allowed_values
41
+ end
31
42
 
32
- class AnalyseError < SDKError
33
- def initialize(something)
34
- super "Analyse Error when \"#{something}\"."
35
- end
36
- end
37
- end
43
+ def message
44
+ "\"#{@parameter_name}\" value \"#{@parameter_value}\" is not allowed, should be one of #{@allowed_values.join ', '}."
45
+ end
38
46
  end
39
- end
47
+ end
48
+ end
@@ -0,0 +1,54 @@
1
+ # +-------------------------------------------------------------------------
2
+ # | Copyright (C) 2016 Yunify, Inc.
3
+ # +-------------------------------------------------------------------------
4
+ # | Licensed under the Apache License, Version 2.0 (the "License");
5
+ # | you may not use this work except in compliance with the License.
6
+ # | You may obtain a copy of the License in the LICENSE file, or at:
7
+ # |
8
+ # | http://www.apache.org/licenses/LICENSE-2.0
9
+ # |
10
+ # | Unless required by applicable law or agreed to in writing, software
11
+ # | distributed under the License is distributed on an "AS IS" BASIS,
12
+ # | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # | See the License for the specific language governing permissions and
14
+ # | limitations under the License.
15
+ # +-------------------------------------------------------------------------
16
+
17
+ require 'active_support/logger'
18
+
19
+ module QingCloud
20
+ module SDK
21
+ class Logger
22
+ @@logger = ActiveSupport::Logger.new STDOUT
23
+ @@level = :warn
24
+
25
+ def self.set_level(level)
26
+ index = %w(debug info warn error fatal).find_index level.to_s
27
+ @@logger.level = index.nil? ? 0 : index
28
+ @@level = level.to_sym
29
+ end
30
+
31
+ set_level :warn
32
+
33
+ def self.debug(text)
34
+ @@logger.debug text
35
+ end
36
+
37
+ def self.info(text)
38
+ @@logger.info text
39
+ end
40
+
41
+ def self.warn(text)
42
+ @@logger.warn text
43
+ end
44
+
45
+ def self.error(text)
46
+ @@logger.error text
47
+ end
48
+
49
+ def self.fatal(text)
50
+ @@logger.fatal text
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,81 @@
1
+ # +-------------------------------------------------------------------------
2
+ # | Copyright (C) 2016 Yunify, Inc.
3
+ # +-------------------------------------------------------------------------
4
+ # | Licensed under the Apache License, Version 2.0 (the "License");
5
+ # | you may not use this work except in compliance with the License.
6
+ # | You may obtain a copy of the License in the LICENSE file, or at:
7
+ # |
8
+ # | http://www.apache.org/licenses/LICENSE-2.0
9
+ # |
10
+ # | Unless required by applicable law or agreed to in writing, software
11
+ # | distributed under the License is distributed on an "AS IS" BASIS,
12
+ # | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # | See the License for the specific language governing permissions and
14
+ # | limitations under the License.
15
+ # +-------------------------------------------------------------------------
16
+
17
+ require 'active_support/core_ext/hash/keys'
18
+
19
+ module QingCloud
20
+ module SDK
21
+ class Preprocessor
22
+ def self.do(input)
23
+ input = decorate_input input
24
+
25
+ config = input[:config]
26
+ input[:request_endpoint] = "#{config[:protocol]}://#{config[:host]}:#{config[:port]}"
27
+
28
+ parsed_params = {}
29
+ input[:request_params].each do |param_k, param_v|
30
+ if param_v.is_a? Array
31
+ param_v.each_with_index do |value, index|
32
+ if value.is_a? Hash
33
+ value.each do |value_k, value_v|
34
+ parsed_params["#{param_k}.#{index}.#{value_k}"] = value_v
35
+ end
36
+ else
37
+ parsed_params["#{param_k}.#{index}"] = value
38
+ end
39
+ end
40
+ elsif param_v.is_a? Hash
41
+ param_v.each do |key, value|
42
+ parsed_params["#{param_k}.#{key}"] = value
43
+ end
44
+ else
45
+ parsed_params[param_k] = param_v
46
+ end
47
+ end
48
+ input[:request_params] = parsed_params.deep_symbolize_keys!
49
+ input[:request_params].update(
50
+ action: input[:api_name],
51
+ time_stamp: Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ'),
52
+ version: 1,
53
+ signature_method: 'HmacSHA256',
54
+ signature_version: 1,
55
+ access_key_id: input[:config][:qy_access_key_id],
56
+ )
57
+
58
+ if input[:properties][:zone] && !input[:properties][:zone].empty?
59
+ input[:request_params][:zone] = input[:properties][:zone]
60
+ end
61
+
62
+ Logger.info "Preprocess QingCloud request: [#{input[:id]}] #{input}"
63
+ input
64
+ end
65
+
66
+ def self.decorate_input(input)
67
+ input.deep_symbolize_keys!
68
+ input[:id] = (Random.new.rand * 1_000_000).to_int
69
+ compact input
70
+ end
71
+
72
+ def self.compact(object)
73
+ object.each do |k, v|
74
+ object[k] = compact v if v.is_a? Hash
75
+ object.delete k if v.nil? || v == ''
76
+ end
77
+ object
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,80 @@
1
+ # +-------------------------------------------------------------------------
2
+ # | Copyright (C) 2016 Yunify, Inc.
3
+ # +-------------------------------------------------------------------------
4
+ # | Licensed under the Apache License, Version 2.0 (the "License");
5
+ # | you may not use this work except in compliance with the License.
6
+ # | You may obtain a copy of the License in the LICENSE file, or at:
7
+ # |
8
+ # | http://www.apache.org/licenses/LICENSE-2.0
9
+ # |
10
+ # | Unless required by applicable law or agreed to in writing, software
11
+ # | distributed under the License is distributed on an "AS IS" BASIS,
12
+ # | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # | See the License for the specific language governing permissions and
14
+ # | limitations under the License.
15
+ # +-------------------------------------------------------------------------
16
+
17
+ require 'json'
18
+ require 'net/http'
19
+ require 'ostruct'
20
+
21
+ module QingCloud
22
+ module SDK
23
+ class Request
24
+ attr_accessor :input, :request_url, :http_request, :http_response
25
+
26
+ def initialize(input)
27
+ self.input = Preprocessor.do input
28
+ end
29
+
30
+ def send
31
+ check
32
+ build
33
+ perform
34
+ unpack
35
+ end
36
+
37
+ private
38
+
39
+ def check
40
+ unless !input[:config][:qy_access_key_id].nil? && !input[:config][:qy_access_key_id].empty?
41
+ raise SDKError, 'access key not provided'
42
+ end
43
+ unless !input[:config][:qy_secret_access_key].nil? && !input[:config][:qy_secret_access_key].empty?
44
+ raise SDKError, 'secret access key not provided'
45
+ end
46
+ end
47
+
48
+ def build
49
+ self.input = Signer.do input
50
+
51
+ params = input[:request_params].map { |k, v| "#{k}=#{v}" }
52
+ query_string = !params.empty? ? "?#{params.join '&'}" : ''
53
+ self.request_url = "#{input[:request_endpoint]}#{input[:config][:uri]}#{query_string}"
54
+
55
+ self.http_request = Net::HTTP::Get.new request_url
56
+ end
57
+
58
+ def perform
59
+ retries = input[:config][:connection_retries]
60
+ while
61
+ begin
62
+ Logger.info "Sending request: [#{input[:id]}] #{request_url}"
63
+ self.http_response = input[:config].connection.request request_url, http_request
64
+ rescue SocketError
65
+ retries > 0 ? retries -= 1 : (raise NetworkError)
66
+ sleep 1
67
+ next
68
+ end
69
+ break
70
+ end
71
+ end
72
+
73
+ def unpack
74
+ output = JSON.parse(http_response.body)
75
+ Logger.info "Parse response: [#{input[:id]}] #{output}"
76
+ output.deep_symbolize_keys!
77
+ end
78
+ end
79
+ end
80
+ end