visor-common 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/visor-config +2 -2
- data/lib/common/config.rb +76 -93
- data/lib/common/exception.rb +1 -1
- data/lib/common/extensions/array.rb +1 -1
- data/lib/common/extensions/hash.rb +1 -1
- data/lib/common/extensions/object.rb +1 -1
- data/lib/common/extensions/yaml.rb +1 -1
- data/lib/common/util.rb +69 -5
- data/lib/common/version.rb +1 -1
- data/spec/lib/config_spec.rb +2 -2
- metadata +2 -2
data/bin/visor-config
CHANGED
@@ -33,10 +33,10 @@ end
|
|
33
33
|
puts "\nGenerating VISOR configuration directories and files:\n\n"
|
34
34
|
sleep (0.5)
|
35
35
|
print "creating #{dir}..."
|
36
|
-
system "mkdir #{dir}"
|
36
|
+
system "mkdir -p #{dir}"
|
37
37
|
puts " [DONE]"
|
38
38
|
print "creating #{dir}/logs..."
|
39
|
-
system "mkdir #{dir}/logs"
|
39
|
+
system "mkdir -p #{dir}/logs"
|
40
40
|
puts " [DONE]"
|
41
41
|
print "creating #{dir}/visor-config.yml..."
|
42
42
|
system "echo '#{Visor::Common::Config::CONFIG_TEMPLATE}' > #{dir}/visor-config.yml"
|
data/lib/common/config.rb
CHANGED
@@ -23,140 +23,124 @@ module Visor
|
|
23
23
|
DEFAULT_LOG_LEVEL = Logger::INFO
|
24
24
|
# Configuration file template
|
25
25
|
CONFIG_TEMPLATE = %q[
|
26
|
-
#
|
27
|
-
#
|
26
|
+
# ===== Default always loaded configuration throughout VISOR sub-systems ======
|
28
27
|
default: &default
|
29
28
|
# Set the default log date time format
|
30
29
|
log_datetime_format: "%Y-%m-%d %H:%M:%S"
|
31
|
-
# Set the default log path
|
30
|
+
# Set the default log files directory path
|
32
31
|
log_path: ~/.visor/logs
|
33
|
-
#
|
34
|
-
access_key:
|
35
|
-
secret_key:
|
32
|
+
# VISOR access and secret key credentials (from visor-admin command)
|
33
|
+
access_key:
|
34
|
+
secret_key:
|
36
35
|
|
37
|
-
# ================================
|
38
|
-
#
|
36
|
+
# ================================ VISOR Auth =================================
|
39
37
|
visor_auth:
|
40
|
-
# Merge default
|
38
|
+
# Merge default configurations
|
41
39
|
<<: *default
|
42
|
-
# Address to bind the
|
40
|
+
# Address and port to bind the server
|
43
41
|
bind_host: 0.0.0.0
|
44
|
-
# Port to bind the meta server
|
45
42
|
bind_port: 4566
|
46
|
-
# Backend connection string (
|
47
|
-
backend: mongodb
|
48
|
-
#
|
49
|
-
# Log file name (
|
43
|
+
# Backend connection string (backend://user:pass@host:port/database)
|
44
|
+
#backend: mongodb://<user>:<password>@<host>:27017/visor
|
45
|
+
#backend: mysql://<user>:<password>@<host>:3306/visor
|
46
|
+
# Log file name (empty for STDOUT)
|
50
47
|
log_file: visor-auth-server.log
|
51
|
-
# Log level to start logging
|
48
|
+
# Log level to start logging events (available: DEBUG, INFO)
|
52
49
|
log_level: INFO
|
53
50
|
|
54
|
-
# ================================
|
55
|
-
#
|
51
|
+
# ================================ VISOR Meta =================================
|
56
52
|
visor_meta:
|
57
|
-
# Merge default
|
53
|
+
# Merge default configurations
|
58
54
|
<<: *default
|
59
|
-
# Address to bind the
|
55
|
+
# Address and port to bind the server
|
60
56
|
bind_host: 0.0.0.0
|
61
|
-
# Port to bind the meta server
|
62
57
|
bind_port: 4567
|
63
|
-
# Backend connection string (
|
64
|
-
backend: mongodb
|
65
|
-
#
|
66
|
-
# Log file name (
|
58
|
+
# Backend connection string (backend://user:pass@host:port/database)
|
59
|
+
#backend: mongodb://<user>:<password>@<host>:27017/visor
|
60
|
+
#backend: mysql://<user>:<password>@<host>:3306/visor
|
61
|
+
# Log file name (empty for STDOUT)
|
67
62
|
log_file: visor-meta-server.log
|
68
|
-
# Log level to start logging
|
63
|
+
# Log level to start logging events (available: DEBUG, INFO)
|
69
64
|
log_level: INFO
|
70
65
|
|
71
|
-
# ================================
|
72
|
-
#
|
66
|
+
# ================================ VISOR Image ================================
|
73
67
|
visor_image:
|
74
|
-
# Merge default
|
68
|
+
# Merge default configurations
|
75
69
|
<<: *default
|
76
|
-
# Address to bind the
|
70
|
+
# Address and port to bind the server
|
77
71
|
bind_host: 0.0.0.0
|
78
|
-
# Port to bind the meta server
|
79
72
|
bind_port: 4568
|
80
|
-
# Log file name (
|
73
|
+
# Log file name (empty for STDOUT)
|
81
74
|
log_file: visor-api-server.log
|
82
|
-
# Log level to start logging
|
75
|
+
# Log level to start logging events (available: DEBUG, INFO)
|
83
76
|
log_level: INFO
|
84
77
|
|
85
|
-
#
|
86
|
-
#
|
78
|
+
# =========================== VISOR Image Backends ============================
|
87
79
|
visor_store:
|
88
|
-
# Default store
|
80
|
+
# Default store (available: s3, lcs, cumulus, walrus, hdfs, file)
|
89
81
|
default: file
|
90
82
|
#
|
91
|
-
# FileSystem store backend settings
|
83
|
+
# FileSystem store backend (file) settings
|
92
84
|
#
|
93
85
|
file:
|
94
86
|
# Default directory to store image files in
|
95
87
|
directory: ~/VMs/
|
96
88
|
#
|
97
|
-
# Amazon
|
89
|
+
# Amazon S3 store backend (s3) settings
|
98
90
|
#
|
99
91
|
s3:
|
100
|
-
# The bucket to store images in, make sure
|
101
|
-
bucket:
|
102
|
-
# Access and secret key credentials, grab yours on your AWS account
|
103
|
-
access_key:
|
104
|
-
secret_key:
|
92
|
+
# The bucket to store images in, make sure it exists on S3
|
93
|
+
bucket:
|
94
|
+
# Access and secret key credentials, grab yours on your AWS account
|
95
|
+
access_key:
|
96
|
+
secret_key:
|
105
97
|
#
|
106
|
-
#
|
98
|
+
# Lunacloud LCS store backend (lcs) settings
|
107
99
|
#
|
108
|
-
|
109
|
-
# The
|
110
|
-
|
111
|
-
#
|
112
|
-
|
113
|
-
|
114
|
-
bucket: XXXXXX
|
115
|
-
# Access and secret key credentials, grab yours with Nimbus cloud
|
116
|
-
access_key: XXXXXX
|
117
|
-
secret_key: XXXXXX
|
100
|
+
lcs:
|
101
|
+
# The bucket to store images in, make sure it exists on LCS
|
102
|
+
bucket:
|
103
|
+
# Access and secret key credentials, grab yours within Lunacloud
|
104
|
+
access_key:
|
105
|
+
secret_key:
|
118
106
|
#
|
119
|
-
#
|
107
|
+
# Nimbus Cumulus store backend (cumulus) settings
|
120
108
|
#
|
121
|
-
|
122
|
-
# The
|
123
|
-
host:
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
#
|
128
|
-
|
129
|
-
|
130
|
-
access_key: XXXXXX
|
131
|
-
secret_key: XXXXXX
|
109
|
+
cumulus:
|
110
|
+
# The Cumulus host address and port number
|
111
|
+
host:
|
112
|
+
port:
|
113
|
+
# The bucket to store images in, make sure it exists on Cumulus
|
114
|
+
bucket:
|
115
|
+
# Access and secret key credentials, grab yours within Nimbus
|
116
|
+
access_key:
|
117
|
+
secret_key:
|
132
118
|
#
|
133
|
-
#
|
119
|
+
# Eucalyptus Walrus store backend (walrus) settings
|
134
120
|
#
|
135
|
-
|
136
|
-
# The
|
137
|
-
host:
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
secret_key: XXXXXX
|
121
|
+
walrus:
|
122
|
+
# The Walrus host address and port number
|
123
|
+
host:
|
124
|
+
port:
|
125
|
+
# The bucket to store images in, make sure it exists on Walrus
|
126
|
+
bucket:
|
127
|
+
# Access and secret key credentials, grab yours within Eucalyptus
|
128
|
+
access_key:
|
129
|
+
secret_key:
|
145
130
|
#
|
146
|
-
# Apache Hadoop HDFS
|
131
|
+
# Apache Hadoop HDFS store backend (hdfs) settings
|
147
132
|
#
|
148
133
|
hdfs:
|
149
|
-
# The HDFS host address
|
150
|
-
host:
|
151
|
-
|
152
|
-
port: XXXXXX
|
134
|
+
# The HDFS host address and port number
|
135
|
+
host:
|
136
|
+
port:
|
153
137
|
# The bucket to store images in
|
154
|
-
bucket:
|
155
|
-
# Access credentials
|
156
|
-
username:
|
138
|
+
bucket:
|
139
|
+
# Access credentials, grab yours within Hadoop
|
140
|
+
username:
|
157
141
|
]
|
158
142
|
|
159
|
-
# Ordered search for a
|
143
|
+
# Ordered search for a VISOR configuration file on default locations and return the first matched.
|
160
144
|
#
|
161
145
|
# @param other_file [String] Other file to use instead of default config files.
|
162
146
|
#
|
@@ -175,17 +159,16 @@ visor_store:
|
|
175
159
|
end
|
176
160
|
end
|
177
161
|
|
178
|
-
# Looks for a
|
179
|
-
# all configuration settings or just a
|
162
|
+
# Looks for a VISOR configuration file through {#self.find_config_file} and returns a hash with
|
163
|
+
# all configuration settings or just a subsystem scoped settings.
|
180
164
|
#
|
181
|
-
# @param scope [String] Used to return just the settings about a specific
|
165
|
+
# @param scope [String] Used to return just the settings about a specific subsystem.
|
182
166
|
# @param other_file [String] Other file to use instead of default config files.
|
183
167
|
#
|
184
168
|
# @return [Hash] Global or scoped settings.
|
185
169
|
#
|
186
170
|
# @raise [RuntimeError] If there is no configuration files or if errors occur during parsing.
|
187
171
|
#
|
188
|
-
#TODO: YAML.load_openstruct(File.read(file))
|
189
172
|
def self.load_config(scope = nil, other_file = nil)
|
190
173
|
file = find_config_file(other_file)
|
191
174
|
raise ConfigError, "Could not found any configuration file." unless file
|
@@ -198,10 +181,10 @@ visor_store:
|
|
198
181
|
config.merge(file: file)
|
199
182
|
end
|
200
183
|
|
201
|
-
# Build and return a Logger instance for a given
|
202
|
-
# file options, which are validated
|
184
|
+
# Build and return a Logger instance for a given VISOR subsystem, based on configuration
|
185
|
+
# file options, which are validated through {#self.validate_logger}.
|
203
186
|
#
|
204
|
-
# @param app_name [Symbol] The
|
187
|
+
# @param app_name [Symbol] The VISOR subsystem app name to build a log for.
|
205
188
|
# @option configs [Hash] Optional configuration options to override config file ones.
|
206
189
|
#
|
207
190
|
# @return [Logger] A logger instance already properly configured.
|
data/lib/common/exception.rb
CHANGED
@@ -2,7 +2,7 @@ module Visor
|
|
2
2
|
module Common
|
3
3
|
|
4
4
|
# The Module Extensions provides a set of functions to extend the Standard Core Libraries
|
5
|
-
# with custom
|
5
|
+
# with custom useful methods used along all VISOR subsystems.
|
6
6
|
#
|
7
7
|
module Extensions
|
8
8
|
#
|
@@ -4,7 +4,7 @@ module Visor
|
|
4
4
|
module Common
|
5
5
|
|
6
6
|
# The Module Extensions provides a set of functions to extend the Standard Core Libraries
|
7
|
-
# with custom
|
7
|
+
# with custom useful methods used along all VISOR subsystems.
|
8
8
|
#
|
9
9
|
module Extensions
|
10
10
|
#
|
@@ -2,7 +2,7 @@ module Visor
|
|
2
2
|
module Common
|
3
3
|
|
4
4
|
# The Module Extensions provides a set of functions to extend the Standard Core Libraries
|
5
|
-
# with custom
|
5
|
+
# with custom useful methods used along all VISOR subsystems.
|
6
6
|
#
|
7
7
|
module Extensions
|
8
8
|
#
|
@@ -2,7 +2,7 @@ module Visor
|
|
2
2
|
module Common
|
3
3
|
|
4
4
|
# The Module Extensions provides a set of functions to extend the Standard Core Libraries
|
5
|
-
# with custom
|
5
|
+
# with custom useful methods used along all VISOR subsystems.
|
6
6
|
#
|
7
7
|
module Extensions
|
8
8
|
#
|
data/lib/common/util.rb
CHANGED
@@ -5,7 +5,7 @@ require 'base64'
|
|
5
5
|
module Visor
|
6
6
|
module Common
|
7
7
|
|
8
|
-
# The Util module provides a set of utility functions used along all
|
8
|
+
# The Util module provides a set of utility functions used along all VISOR subsystems.
|
9
9
|
#
|
10
10
|
module Util
|
11
11
|
extend self
|
@@ -14,7 +14,7 @@ module Visor
|
|
14
14
|
# Each key value pair is pushed as a string of the form 'x-image-meta-<key>'.
|
15
15
|
#
|
16
16
|
# @param meta [Hash] The image metadata
|
17
|
-
# @param
|
17
|
+
# @param headers [Hash] (nil) The HTTP headers hash
|
18
18
|
#
|
19
19
|
# @return [Hash] The header containing the metadata headers
|
20
20
|
#
|
@@ -23,6 +23,12 @@ module Visor
|
|
23
23
|
headers
|
24
24
|
end
|
25
25
|
|
26
|
+
# Pull image metadata from HTTP headers to a hash.
|
27
|
+
#
|
28
|
+
# @param headers [Hash] (nil) The HTTP headers hash
|
29
|
+
#
|
30
|
+
# @return [Hash] The header containing the metadata
|
31
|
+
#
|
26
32
|
def pull_meta_from_headers(headers)
|
27
33
|
meta = {}
|
28
34
|
headers.each do |k, v|
|
@@ -34,6 +40,13 @@ module Visor
|
|
34
40
|
meta
|
35
41
|
end
|
36
42
|
|
43
|
+
# Find if a string value is an integer, a float or a date. If it matches a type,
|
44
|
+
# then it is converted to that type and returned.
|
45
|
+
#
|
46
|
+
# @param string [String] The string to be parsed.
|
47
|
+
#
|
48
|
+
# @return [Object] The already converted string value.
|
49
|
+
#
|
37
50
|
def parse_value(string)
|
38
51
|
if is_integer?(string) then
|
39
52
|
Integer(string)
|
@@ -46,19 +59,45 @@ module Visor
|
|
46
59
|
end
|
47
60
|
end
|
48
61
|
|
62
|
+
# Find if a an object can be converted to an integer.
|
63
|
+
#
|
64
|
+
# @param object [Object] The object to be converted to integer.
|
65
|
+
#
|
66
|
+
# @return [Integer,NilClass] The converted integer, or nil if it can not be converted to integer.
|
67
|
+
#
|
49
68
|
def is_integer?(object)
|
50
69
|
true if Integer(object) rescue false
|
51
70
|
end
|
52
71
|
|
72
|
+
# Find if a an object can be converted to a float.
|
73
|
+
#
|
74
|
+
# @param object [Object] The object to be converted to a float.
|
75
|
+
#
|
76
|
+
# @return [Float,NilClass] The converted float, or nil if it can not be converted to a float.
|
77
|
+
#
|
53
78
|
def is_float?(object)
|
54
79
|
true if Float(object) rescue false
|
55
80
|
end
|
56
81
|
|
82
|
+
# Find if a an object can be converted to a date.
|
83
|
+
#
|
84
|
+
# @param object [Object] The object to be converted to a date.
|
85
|
+
#
|
86
|
+
# @return [Date,NilClass] The converted float, or nil if it can not be converted to a date.
|
87
|
+
#
|
57
88
|
def is_date?(object)
|
58
89
|
regexp = /\d{4}[-\/]\d{1,2}[-\/]\d{1,2}\s\d{2}:\d{2}:\d{2}\s\W\d{4}/
|
59
90
|
object.match(regexp) ? true : false
|
60
91
|
end
|
61
92
|
|
93
|
+
# Sign a request by generating an authorization string and embedding it in the request headers.
|
94
|
+
#
|
95
|
+
# @param access_key [String] The requester user access key.
|
96
|
+
# @param secret_key [String] The requester user secret key.
|
97
|
+
# @param method [String] The request method.
|
98
|
+
# @param path [String] The request path.
|
99
|
+
# @param headers [Hash] The request headers.
|
100
|
+
#
|
62
101
|
def sign_request(access_key, secret_key, method, path, headers={})
|
63
102
|
headers['Date'] ||= Time.now.utc.httpdate
|
64
103
|
desc = canonical_description(method, path, headers)
|
@@ -67,6 +106,14 @@ module Visor
|
|
67
106
|
headers['Authorization'] = "VISOR #{access_key}:#{signature}"
|
68
107
|
end
|
69
108
|
|
109
|
+
# Generate a request canonical description, which will be used by {#sign_request}.
|
110
|
+
#
|
111
|
+
# @param method [String] The request method.
|
112
|
+
# @param path [String] The request path.
|
113
|
+
# @param headers [Hash] The request headers.
|
114
|
+
#
|
115
|
+
# @return [String] The request canonical description string.
|
116
|
+
#
|
70
117
|
def canonical_description(method, path, headers={})
|
71
118
|
attributes = {}
|
72
119
|
headers.each do |key, value|
|
@@ -84,12 +131,31 @@ module Visor
|
|
84
131
|
desc << path.gsub(/\?.*$/, '')
|
85
132
|
end
|
86
133
|
|
134
|
+
# Authenticate an user request by analysing the request authorization string.
|
135
|
+
#
|
136
|
+
# @param env [Hash] The request attributes.
|
137
|
+
# @param vas [Visor::Image::Auth] A VAS interface object, used to query for user credentials.
|
138
|
+
#
|
139
|
+
# @return [String] The authenticated user access key.
|
140
|
+
#
|
141
|
+
# @raise [Forbidden] If authorization header was not provided along the request.
|
142
|
+
# @raise [Forbidden] If no access key found in the authorization header string.
|
143
|
+
# @raise [Forbidden] If no user found with the given access key.
|
144
|
+
# @raise [Forbidden] If signatures do not match.
|
145
|
+
# @raise [InternalError] If VAS server was not found.
|
146
|
+
#
|
87
147
|
def authorize(env, vas)
|
88
148
|
auth = env['headers']['Authorization']
|
89
149
|
raise Visor::Common::Exception::Forbidden, "Authorization not provided." unless auth
|
90
150
|
access_key = auth.scan(/\ (\w+):/).flatten.first
|
91
151
|
raise Visor::Common::Exception::Forbidden, "No access key found in Authorization." unless access_key
|
92
|
-
|
152
|
+
begin
|
153
|
+
user = vas.get_user(access_key)
|
154
|
+
rescue Visor::Common::Exception::InternalError => e
|
155
|
+
raise Visor::Common::Exception::InternalError, e.message
|
156
|
+
rescue => e
|
157
|
+
nil
|
158
|
+
end
|
93
159
|
raise Visor::Common::Exception::Forbidden, "No user found with access key '#{access_key}'." unless user
|
94
160
|
sign = sign_request(user[:access_key], user[:secret_key], env['REQUEST_METHOD'], env['REQUEST_PATH'], env['headers'])
|
95
161
|
raise Visor::Common::Exception::Forbidden, "Invalid authorization, signatures do not match." unless auth == sign
|
@@ -99,5 +165,3 @@ module Visor
|
|
99
165
|
end
|
100
166
|
end
|
101
167
|
end
|
102
|
-
|
103
|
-
#sign_request('key', 'secret', 'GET', '/users/joaodrp', {'x-image-meta-name' => 'hi'})
|
data/lib/common/version.rb
CHANGED
data/spec/lib/config_spec.rb
CHANGED
@@ -68,7 +68,7 @@ module Visor::Common
|
|
68
68
|
|
69
69
|
it "should return scoped configuration" do
|
70
70
|
conf = Config.load_config :default
|
71
|
-
conf.keys.should == sample_conf[:default].keys << :file
|
71
|
+
conf.keys.should == sample_conf[:default].keys << :access_key << :secret_key << :file
|
72
72
|
end
|
73
73
|
|
74
74
|
it "should raise an exception if an error occurs during parsing" do
|
@@ -88,7 +88,7 @@ module Visor::Common
|
|
88
88
|
|
89
89
|
it "should set the log level if provided" do
|
90
90
|
log = Config.build_logger :visor_meta, sample_conf
|
91
|
-
log.level.
|
91
|
+
log.level.should_not == Logger::DEBUG
|
92
92
|
end
|
93
93
|
|
94
94
|
it "should set the log level to the default if not provided" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: visor-common
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|