miasma 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/LICENSE +13 -0
- data/README.md +18 -3
- data/lib/miasma/contrib/aws.rb +18 -1
- data/lib/miasma/contrib/aws/orchestration.rb +3 -3
- data/lib/miasma/contrib/aws/storage.rb +330 -0
- data/lib/miasma/contrib/open_stack.rb +334 -0
- data/lib/miasma/contrib/open_stack/compute.rb +105 -0
- data/lib/miasma/contrib/open_stack/orchestration.rb +255 -0
- data/lib/miasma/contrib/rackspace.rb +34 -94
- data/lib/miasma/contrib/rackspace/compute.rb +1 -92
- data/lib/miasma/contrib/rackspace/orchestration.rb +1 -231
- data/lib/miasma/error.rb +7 -5
- data/lib/miasma/models/orchestration/resource.rb +1 -1
- data/lib/miasma/models/orchestration/stack.rb +2 -2
- data/lib/miasma/models/storage.rb +36 -8
- data/lib/miasma/models/storage/bucket.rb +23 -10
- data/lib/miasma/models/storage/file.rb +44 -4
- data/lib/miasma/models/storage/files.rb +6 -1
- data/lib/miasma/types/api.rb +10 -4
- data/lib/miasma/types/model.rb +4 -1
- data/lib/miasma/utils/lazy.rb +7 -2
- data/lib/miasma/version.rb +1 -1
- data/miasma.gemspec +2 -1
- metadata +21 -2
data/lib/miasma/error.rb
CHANGED
@@ -29,6 +29,7 @@ module Miasma
|
|
29
29
|
def initialize(msg, args={})
|
30
30
|
super
|
31
31
|
@response = args.to_smash[:response]
|
32
|
+
@message = msg
|
32
33
|
extract_error_message(@response)
|
33
34
|
end
|
34
35
|
|
@@ -54,9 +55,11 @@ module Miasma
|
|
54
55
|
rescue MultiJson::ParseError
|
55
56
|
begin
|
56
57
|
content = MultiXml.parse(response.body.to_s).to_smash
|
57
|
-
|
58
|
-
|
59
|
-
|
58
|
+
@response_error_msg = [['ErrorResponse', 'Error'], ['Error']].map do |path|
|
59
|
+
if(result = content.get(*path))
|
60
|
+
"#{result['Code']}: #{result['Message']}"
|
61
|
+
end
|
62
|
+
end.compact.first
|
60
63
|
rescue MultiXml::ParseError
|
61
64
|
content = Smash.new
|
62
65
|
end
|
@@ -78,8 +81,7 @@ module Miasma
|
|
78
81
|
# Orchestration error
|
79
82
|
class OrchestrationError < Error
|
80
83
|
# Template failed to validate
|
81
|
-
class InvalidTemplate < OrchestrationError
|
82
|
-
end
|
84
|
+
class InvalidTemplate < OrchestrationError; end
|
83
85
|
end
|
84
86
|
|
85
87
|
# Invalid modification request
|
@@ -14,7 +14,7 @@ module Miasma
|
|
14
14
|
attribute :state, Symbol, :required => true, :allowed_values => Orchestration::VALID_RESOURCE_STATES
|
15
15
|
attribute :status, [String, Symbol], :required => true, :coerce => lambda{|v| v.to_s.to_sym}
|
16
16
|
attribute :status_reason, String
|
17
|
-
attribute :
|
17
|
+
attribute :updated, Time, :coerce => lambda{|v| Time.parse(v.to_s)}
|
18
18
|
|
19
19
|
attr_reader :stack
|
20
20
|
|
@@ -35,8 +35,8 @@ module Miasma
|
|
35
35
|
attribute :outputs, Output, :coerce => lambda{|v, stack| Output.new(stack, v) }, :multiple => true
|
36
36
|
attribute :status, String
|
37
37
|
attribute :status_reason, String
|
38
|
-
attribute :
|
39
|
-
attribute :
|
38
|
+
attribute :created, Time, :coerce => lambda{|v| Time.parse(v.to_s)}
|
39
|
+
attribute :updated, Time, :coerce => lambda{|v| Time.parse(v.to_s)}
|
40
40
|
attribute :parameters, Smash, :coerce => lambda{|v| v.to_smash }
|
41
41
|
attribute :template, Smash, :depends => :perform_template_load, :coerce => lambda{|v| v = MultiJson.load(v) if v.is_a?(String); v.to_smash }
|
42
42
|
attribute :template_url, String
|
@@ -5,19 +5,26 @@ module Miasma
|
|
5
5
|
# Abstract storage API
|
6
6
|
class Storage < Types::Api
|
7
7
|
|
8
|
+
autoload :Buckets, 'miasma/models/storage/buckets'
|
9
|
+
autoload :Bucket, 'miasma/models/storage/bucket'
|
10
|
+
autoload :Files, 'miasma/models/storage/files'
|
11
|
+
autoload :File, 'miasma/models/storage/file'
|
12
|
+
|
8
13
|
# Storage buckets
|
9
14
|
#
|
10
15
|
# @param filter [Hash] filtering options
|
11
16
|
# @return [Types::Collection<Models::Storage::Bucket>] buckets
|
12
17
|
def buckets(args={})
|
13
|
-
|
18
|
+
memoize(:buckets) do
|
19
|
+
Buckets.new(self)
|
20
|
+
end
|
14
21
|
end
|
15
22
|
|
16
|
-
#
|
23
|
+
# Save bucket
|
17
24
|
#
|
18
25
|
# @param bucket [Models::Storage::Bucket]
|
19
26
|
# @return [Models::Storage::Bucket]
|
20
|
-
def
|
27
|
+
def bucket_save(bucket)
|
21
28
|
raise NotImplementedError
|
22
29
|
end
|
23
30
|
|
@@ -25,16 +32,15 @@ module Miasma
|
|
25
32
|
#
|
26
33
|
# @param bucket [Models::Storage::Bucket]
|
27
34
|
# @return [TrueClass, FalseClass]
|
28
|
-
def
|
35
|
+
def bucket_destroy(bucket)
|
29
36
|
raise NotImplementedError
|
30
37
|
end
|
31
38
|
|
32
|
-
#
|
39
|
+
# Reload the bucket
|
33
40
|
#
|
34
41
|
# @param bucket [Models::Storage::Bucket]
|
35
|
-
# @
|
36
|
-
|
37
|
-
def bucket_rename(bucket, new_name)
|
42
|
+
# @return [Models::Storage::Bucket]
|
43
|
+
def bucket_reload(bucket)
|
38
44
|
raise NotImplementedError
|
39
45
|
end
|
40
46
|
|
@@ -53,7 +59,29 @@ module Miasma
|
|
53
59
|
raise NotImplementedError
|
54
60
|
end
|
55
61
|
|
62
|
+
# Save file
|
63
|
+
#
|
64
|
+
# @param file [Models::Storage::File]
|
65
|
+
# @return [Models::Storage::File]
|
66
|
+
def file_save(file)
|
67
|
+
raise NotImplementedError
|
68
|
+
end
|
56
69
|
|
70
|
+
# Destroy file
|
71
|
+
#
|
72
|
+
# @param file [Models::Storage::File]
|
73
|
+
# @return [TrueClass, FalseClass]
|
74
|
+
def file_destroy(file)
|
75
|
+
raise NotImplementedError
|
76
|
+
end
|
77
|
+
|
78
|
+
# Reload the file
|
79
|
+
#
|
80
|
+
# @param file [Models::Storage::File]
|
81
|
+
# @return [Models::Storage::File]
|
82
|
+
def file_reload(file)
|
83
|
+
raise NotImplementedError
|
84
|
+
end
|
57
85
|
|
58
86
|
end
|
59
87
|
end
|
@@ -6,27 +6,40 @@ module Miasma
|
|
6
6
|
# Abstract bucket
|
7
7
|
class Bucket < Types::Model
|
8
8
|
|
9
|
-
attribute :
|
9
|
+
attribute :name, String, :required => true
|
10
|
+
attribute :created, Time, :coerce => lambda{|t| Time.parse(t.to_s)}
|
11
|
+
attribute :metadata, Smash, :coerce => lambda{|o| o.to_smash}
|
12
|
+
|
13
|
+
# @return [Files]
|
14
|
+
def files
|
15
|
+
memoize(:files) do
|
16
|
+
Files.new(self)
|
17
|
+
end
|
18
|
+
end
|
10
19
|
|
11
20
|
# Filter buckets
|
12
21
|
#
|
13
22
|
# @param filter [Hash]
|
14
23
|
# @return [Array<Bucket>]
|
15
24
|
def filter(filter={})
|
25
|
+
raise NotImplementedError
|
16
26
|
end
|
17
27
|
|
18
|
-
|
19
|
-
|
20
|
-
#
|
21
|
-
|
22
|
-
|
23
|
-
perform_rename(new_name)
|
28
|
+
protected
|
29
|
+
|
30
|
+
# Proxy reload action up to the API
|
31
|
+
def perform_reload
|
32
|
+
api.bucket_reload(self)
|
24
33
|
end
|
25
34
|
|
26
|
-
|
35
|
+
# Proxy save action up to the API
|
36
|
+
def perform_save
|
37
|
+
api.bucket_save(self)
|
38
|
+
end
|
27
39
|
|
28
|
-
|
29
|
-
|
40
|
+
# Proxy destroy action up to the API
|
41
|
+
def perform_destroy
|
42
|
+
api.bucket_destroy(self)
|
30
43
|
end
|
31
44
|
|
32
45
|
end
|
@@ -6,15 +6,18 @@ module Miasma
|
|
6
6
|
class Storage
|
7
7
|
|
8
8
|
# Abstract file
|
9
|
-
class File < Types::
|
9
|
+
class File < Types::Model
|
10
10
|
|
11
|
-
attribute :
|
11
|
+
attribute :name, String, :required => true
|
12
12
|
attribute :content_type, String
|
13
13
|
attribute :content_disposition, String
|
14
|
+
attribute :content_encoding, String
|
14
15
|
attribute :etag, String
|
15
|
-
attribute :
|
16
|
+
attribute :updated, Time, :coerce => lambda{|t| Time.parse(t.to_s)}
|
16
17
|
attribute :size, Integer
|
17
|
-
attribute :metadata,
|
18
|
+
attribute :metadata, Smash, :coerce => lambda{|o| o.to_smash}
|
19
|
+
|
20
|
+
on_missing :reload
|
18
21
|
|
19
22
|
# @return [Bucket] parent bucket
|
20
23
|
attr_reader :bucket
|
@@ -38,6 +41,43 @@ module Miasma
|
|
38
41
|
raise NotImplementedError
|
39
42
|
end
|
40
43
|
|
44
|
+
# @return [IO-ish]
|
45
|
+
# @note object returned will provide #readpartial
|
46
|
+
def body
|
47
|
+
unless(attributes[:body])
|
48
|
+
data[:body] ||= api.file_body(self)
|
49
|
+
end
|
50
|
+
attributes[:body]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Set file body
|
54
|
+
#
|
55
|
+
# @param io [IO, String]
|
56
|
+
# @return [IO]
|
57
|
+
def body=(io)
|
58
|
+
unless(io.is_a?(IO))
|
59
|
+
io = StringIO.new(io)
|
60
|
+
end
|
61
|
+
dirty[:body] = io
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
# Proxy reload action up to the API
|
67
|
+
def perform_reload
|
68
|
+
api.file_reload(self)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Proxy save action up to the API
|
72
|
+
def perform_save
|
73
|
+
api.file_save(self)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Proxy destroy action up to the API
|
77
|
+
def perform_destroy
|
78
|
+
api.file_destroy(self)
|
79
|
+
end
|
80
|
+
|
41
81
|
end
|
42
82
|
|
43
83
|
end
|
@@ -30,7 +30,12 @@ module Miasma
|
|
30
30
|
|
31
31
|
# @return [File] new unsaved instance
|
32
32
|
def build(args={})
|
33
|
-
|
33
|
+
instance = self.model.new(bucket)
|
34
|
+
args.each do |m_name, m_value|
|
35
|
+
m_name = "#{m_name}="
|
36
|
+
instance.send(m_name, m_value)
|
37
|
+
end
|
38
|
+
instance
|
34
39
|
end
|
35
40
|
|
36
41
|
# @return [File] collection item class
|
data/lib/miasma/types/api.rb
CHANGED
@@ -75,8 +75,9 @@ module Miasma
|
|
75
75
|
raise ArgumentError.new 'Invalid request method provided!'
|
76
76
|
end
|
77
77
|
request_args = [].tap do |ary|
|
78
|
+
_endpoint = args.delete(:endpoint) || endpoint
|
78
79
|
ary.push(
|
79
|
-
File.join(
|
80
|
+
File.join(_endpoint, args[:path].to_s)
|
80
81
|
)
|
81
82
|
options = {}.tap do |opts|
|
82
83
|
[:form, :params, :json, :body].each do |key|
|
@@ -117,20 +118,25 @@ module Miasma
|
|
117
118
|
# @return [Smash]
|
118
119
|
def format_response(result)
|
119
120
|
extracted_headers = Smash[result.headers.map{|k,v| [Utils.snake(k), v]}]
|
120
|
-
if(extracted_headers[:content_type].
|
121
|
+
if(extracted_headers[:content_type].to_s.end_with?('json'))
|
121
122
|
begin
|
122
123
|
extracted_body = MultiJson.load(result.body.to_s).to_smash
|
123
124
|
rescue MultiJson::ParseError
|
124
125
|
extracted_body = result.body.to_s
|
125
126
|
end
|
126
|
-
elsif(extracted_headers[:content_type].
|
127
|
+
elsif(extracted_headers[:content_type].to_s.end_with?('xml'))
|
127
128
|
begin
|
128
129
|
extracted_body = MultiXml.parse(result.body.to_s).to_smash
|
129
130
|
rescue MultiXml::ParseError
|
130
131
|
extracted_body = result.body.to_s
|
131
132
|
end
|
132
133
|
else
|
133
|
-
|
134
|
+
# @note if body is over 100KB, do not extract
|
135
|
+
if(extracted_headers[:content_length].to_i < 102400)
|
136
|
+
extracted_body = result.body.to_s
|
137
|
+
else
|
138
|
+
extracted_body = result.body
|
139
|
+
end
|
134
140
|
end
|
135
141
|
Smash.new(
|
136
142
|
:response => result,
|
data/lib/miasma/types/model.rb
CHANGED
@@ -6,6 +6,8 @@ module Miasma
|
|
6
6
|
# Base model
|
7
7
|
class Model < Data
|
8
8
|
|
9
|
+
include Utils::Memoization
|
10
|
+
|
9
11
|
# @return [Miasma::Types::Api] underlying service API
|
10
12
|
attr_reader :api
|
11
13
|
|
@@ -35,7 +37,7 @@ module Miasma
|
|
35
37
|
@dirty = Smash.new
|
36
38
|
if(model_data)
|
37
39
|
if(model_data.is_a?(Hash))
|
38
|
-
load_data(model_data)
|
40
|
+
load_data(model_data) unless model_data.empty?
|
39
41
|
else
|
40
42
|
raise TypeError.new "Expecting `model_data` to be of type `Hash`. Received: `#{model_data.class}`"
|
41
43
|
end
|
@@ -73,6 +75,7 @@ module Miasma
|
|
73
75
|
#
|
74
76
|
# @return [self]
|
75
77
|
def reload
|
78
|
+
clear_memoizations!
|
76
79
|
perform_reload
|
77
80
|
self
|
78
81
|
end
|
data/lib/miasma/utils/lazy.rb
CHANGED
@@ -182,8 +182,13 @@ module Miasma
|
|
182
182
|
if(param.is_a?(Symbol))
|
183
183
|
@missing_method = param
|
184
184
|
else
|
185
|
-
if(@missing_method)
|
186
|
-
|
185
|
+
if(@missing_method && !@calling_on_missing)
|
186
|
+
@calling_on_missing = true
|
187
|
+
begin
|
188
|
+
param.send(@missing_method)
|
189
|
+
ensure
|
190
|
+
@calling_on_missing = false
|
191
|
+
end
|
187
192
|
end
|
188
193
|
@missing_method
|
189
194
|
end
|
data/lib/miasma/version.rb
CHANGED
data/miasma.gemspec
CHANGED
@@ -14,5 +14,6 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.add_dependency 'http'
|
15
15
|
s.add_dependency 'multi_json'
|
16
16
|
s.add_dependency 'multi_xml'
|
17
|
-
s.
|
17
|
+
s.add_dependency 'xml-simple'
|
18
|
+
s.files = Dir['lib/**/*'] + %w(miasma.gemspec README.md CHANGELOG.md LICENSE)
|
18
19
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: miasma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: xml-simple
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
description: Smoggy API
|
70
84
|
email: code@chrisroberts.org
|
71
85
|
executables: []
|
@@ -73,6 +87,7 @@ extensions: []
|
|
73
87
|
extra_rdoc_files: []
|
74
88
|
files:
|
75
89
|
- CHANGELOG.md
|
90
|
+
- LICENSE
|
76
91
|
- README.md
|
77
92
|
- lib/miasma.rb
|
78
93
|
- lib/miasma/contrib/aws.rb
|
@@ -80,6 +95,10 @@ files:
|
|
80
95
|
- lib/miasma/contrib/aws/compute.rb
|
81
96
|
- lib/miasma/contrib/aws/load_balancer.rb
|
82
97
|
- lib/miasma/contrib/aws/orchestration.rb
|
98
|
+
- lib/miasma/contrib/aws/storage.rb
|
99
|
+
- lib/miasma/contrib/open_stack.rb
|
100
|
+
- lib/miasma/contrib/open_stack/compute.rb
|
101
|
+
- lib/miasma/contrib/open_stack/orchestration.rb
|
83
102
|
- lib/miasma/contrib/rackspace.rb
|
84
103
|
- lib/miasma/contrib/rackspace/auto_scale.rb
|
85
104
|
- lib/miasma/contrib/rackspace/compute.rb
|