miasma 0.0.1 → 0.1.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 +2 -0
- data/README.md +179 -0
- data/lib/miasma.rb +52 -0
- data/lib/miasma/contrib/aws.rb +390 -0
- data/lib/miasma/contrib/aws/auto_scale.rb +85 -0
- data/lib/miasma/contrib/aws/compute.rb +112 -0
- data/lib/miasma/contrib/aws/load_balancer.rb +185 -0
- data/lib/miasma/contrib/aws/orchestration.rb +338 -0
- data/lib/miasma/contrib/rackspace.rb +164 -0
- data/lib/miasma/contrib/rackspace/auto_scale.rb +84 -0
- data/lib/miasma/contrib/rackspace/compute.rb +104 -0
- data/lib/miasma/contrib/rackspace/load_balancer.rb +117 -0
- data/lib/miasma/contrib/rackspace/orchestration.rb +255 -0
- data/lib/miasma/error.rb +89 -0
- data/lib/miasma/models.rb +14 -0
- data/lib/miasma/models/auto_scale.rb +55 -0
- data/lib/miasma/models/auto_scale/group.rb +64 -0
- data/lib/miasma/models/auto_scale/groups.rb +34 -0
- data/lib/miasma/models/block_storage.rb +0 -0
- data/lib/miasma/models/compute.rb +70 -0
- data/lib/miasma/models/compute/server.rb +71 -0
- data/lib/miasma/models/compute/servers.rb +35 -0
- data/lib/miasma/models/dns.rb +0 -0
- data/lib/miasma/models/load_balancer.rb +55 -0
- data/lib/miasma/models/load_balancer/balancer.rb +72 -0
- data/lib/miasma/models/load_balancer/balancers.rb +34 -0
- data/lib/miasma/models/monitoring.rb +0 -0
- data/lib/miasma/models/orchestration.rb +127 -0
- data/lib/miasma/models/orchestration/event.rb +38 -0
- data/lib/miasma/models/orchestration/events.rb +64 -0
- data/lib/miasma/models/orchestration/resource.rb +79 -0
- data/lib/miasma/models/orchestration/resources.rb +55 -0
- data/lib/miasma/models/orchestration/stack.rb +144 -0
- data/lib/miasma/models/orchestration/stacks.rb +46 -0
- data/lib/miasma/models/queues.rb +0 -0
- data/lib/miasma/models/storage.rb +60 -0
- data/lib/miasma/models/storage/bucket.rb +36 -0
- data/lib/miasma/models/storage/buckets.rb +41 -0
- data/lib/miasma/models/storage/file.rb +45 -0
- data/lib/miasma/models/storage/files.rb +52 -0
- data/lib/miasma/types.rb +13 -0
- data/lib/miasma/types/api.rb +145 -0
- data/lib/miasma/types/collection.rb +116 -0
- data/lib/miasma/types/data.rb +53 -0
- data/lib/miasma/types/model.rb +118 -0
- data/lib/miasma/types/thin_model.rb +76 -0
- data/lib/miasma/utils.rb +12 -0
- data/lib/miasma/utils/animal_strings.rb +29 -0
- data/lib/miasma/utils/immutable.rb +36 -0
- data/lib/miasma/utils/lazy.rb +231 -0
- data/lib/miasma/utils/memoization.rb +55 -0
- data/lib/miasma/utils/smash.rb +149 -0
- data/lib/miasma/version.rb +4 -0
- data/miasma.gemspec +18 -0
- metadata +57 -3
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'miasma'
|
2
|
+
|
3
|
+
module Miasma
|
4
|
+
module Models
|
5
|
+
class Orchestration
|
6
|
+
class Stack
|
7
|
+
|
8
|
+
# Stack event
|
9
|
+
class Event < Types::Model
|
10
|
+
|
11
|
+
attribute :time, Time, :required => true
|
12
|
+
attribute :resource_id, [String, Numeric], :required => true
|
13
|
+
attribute :resource_logical_id, [String, Numeric]
|
14
|
+
attribute :resource_name, String
|
15
|
+
attribute :resource_state, Symbol, :allowed_values => Orchestration::VALID_RESOURCE_STATES
|
16
|
+
attribute :resource_status, String
|
17
|
+
attribute :resource_status_reason, String
|
18
|
+
|
19
|
+
attr_reader :stack
|
20
|
+
|
21
|
+
def initialize(stack, args={})
|
22
|
+
@stack = stack
|
23
|
+
super stack.api, args
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Resource]
|
27
|
+
def resource
|
28
|
+
stack.resources.get(self.resource_id)
|
29
|
+
end
|
30
|
+
|
31
|
+
include Utils::Immutable
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'miasma'
|
2
|
+
|
3
|
+
module Miasma
|
4
|
+
module Models
|
5
|
+
class Orchestration
|
6
|
+
class Stack
|
7
|
+
|
8
|
+
# Abstract stack resources collection
|
9
|
+
class Events < Types::Collection
|
10
|
+
|
11
|
+
# @return [Miasma::Models::Orchestration::Stack]
|
12
|
+
attr_reader :stack
|
13
|
+
|
14
|
+
# Override to capture originating stack
|
15
|
+
#
|
16
|
+
# @param stack [Stack]
|
17
|
+
def initialize(stack)
|
18
|
+
@stack = stack
|
19
|
+
super stack.api
|
20
|
+
end
|
21
|
+
|
22
|
+
# Return events matching given filter
|
23
|
+
#
|
24
|
+
# @param options [Hash] filter options
|
25
|
+
# @return [Array<Event>]
|
26
|
+
def filter(options={})
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
# Build a new event instance
|
31
|
+
#
|
32
|
+
# @param args [Hash] creation options
|
33
|
+
# @return [Event]
|
34
|
+
def build(args={})
|
35
|
+
Event.new(stack, args.to_smash)
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [Event] collection item class
|
39
|
+
def model
|
40
|
+
Event
|
41
|
+
end
|
42
|
+
|
43
|
+
# Fetch any new events and add to collection
|
44
|
+
#
|
45
|
+
# @return [Array<Event>] new events fetched
|
46
|
+
def update!
|
47
|
+
new_events = api.event_all_new(self)
|
48
|
+
self.all += new_events
|
49
|
+
new_events
|
50
|
+
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
# @return [Array<Event>]
|
55
|
+
def perform_population
|
56
|
+
api.event_all(stack)
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'miasma'
|
2
|
+
|
3
|
+
module Miasma
|
4
|
+
module Models
|
5
|
+
class Orchestration
|
6
|
+
class Stack
|
7
|
+
|
8
|
+
# Stack resource
|
9
|
+
class Resource < Types::Model
|
10
|
+
|
11
|
+
attribute :name, String, :required => true
|
12
|
+
attribute :type, String, :required => true
|
13
|
+
attribute :logical_id, [String, Numeric]
|
14
|
+
attribute :state, Symbol, :required => true, :allowed_values => Orchestration::VALID_RESOURCE_STATES
|
15
|
+
attribute :status, [String, Symbol], :required => true, :coerce => lambda{|v| v.to_s.to_sym}
|
16
|
+
attribute :status_reason, String
|
17
|
+
attribute :updated_time, Time, :coerce => lambda{|v| Time.parse(v.to_s)}
|
18
|
+
|
19
|
+
attr_reader :stack
|
20
|
+
|
21
|
+
def initialize(stack, args={})
|
22
|
+
@stack = stack
|
23
|
+
super stack.api, args
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Miasma::Types::Model] provides mapped resource class
|
27
|
+
def dereference
|
28
|
+
# Insert provider to namespace
|
29
|
+
provider_const = self.class.name.split('::').insert(3, Utils.camel(api.provider))
|
30
|
+
provider_const.slice!(-2, 2)
|
31
|
+
# Insert mapping constant name and fetch
|
32
|
+
const = provider_const.push(:RESOURCE_MAPPING).inject(Object) do |memo, konst|
|
33
|
+
res = memo.const_get(konst)
|
34
|
+
break unless res
|
35
|
+
res
|
36
|
+
end
|
37
|
+
unless(const[self.type])
|
38
|
+
raise KeyError.new "Failed to locate requested mapping! (`#{self.type}`)"
|
39
|
+
end
|
40
|
+
const[self.type]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Provide proper instance from resource
|
44
|
+
#
|
45
|
+
# @return [Miasma::Types::Model]
|
46
|
+
def expand
|
47
|
+
info = dereference
|
48
|
+
api.api_for(info[:api]).send(info[:collection]).get(self.id)
|
49
|
+
end
|
50
|
+
alias_method :instance, :expand
|
51
|
+
|
52
|
+
# Proxy reload action up to the API
|
53
|
+
def perform_reload
|
54
|
+
api.resource_reload(self)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Resource is within the collection on the api
|
58
|
+
#
|
59
|
+
# @param api [Symbol] api type (:compute, :auto_scale, etc)
|
60
|
+
# @param collection [Symbol] collection within api (:servers, :groups, etc)
|
61
|
+
# @return [TrueClass, FalseClass]
|
62
|
+
def within?(api, collection)
|
63
|
+
begin
|
64
|
+
info = dereference
|
65
|
+
info[:api] == api &&
|
66
|
+
info[:collection] == collection
|
67
|
+
rescue KeyError
|
68
|
+
false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
include Utils::Immutable
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'miasma'
|
2
|
+
|
3
|
+
module Miasma
|
4
|
+
module Models
|
5
|
+
class Orchestration
|
6
|
+
class Stack
|
7
|
+
|
8
|
+
# Abstract stack resources collection
|
9
|
+
class Resources < Types::Collection
|
10
|
+
|
11
|
+
# @return [Miasma::Models::Orchestration::Stack]
|
12
|
+
attr_reader :stack
|
13
|
+
|
14
|
+
# Override to capture originating stack
|
15
|
+
#
|
16
|
+
# @param stack [Stack]
|
17
|
+
def initialize(stack)
|
18
|
+
@stack = stack
|
19
|
+
super stack.api
|
20
|
+
end
|
21
|
+
|
22
|
+
# Return resources matching given filter
|
23
|
+
#
|
24
|
+
# @param options [Hash] filter options
|
25
|
+
# @return [Array<Resources>]
|
26
|
+
def filter(options={})
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
# Build a new resource instance
|
31
|
+
#
|
32
|
+
# @param args [Hash] creation options
|
33
|
+
# @return [Resource]
|
34
|
+
def build(args={})
|
35
|
+
Resource.new(stack, args.to_smash)
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [Resource] collection item class
|
39
|
+
def model
|
40
|
+
Resource
|
41
|
+
end
|
42
|
+
|
43
|
+
protected
|
44
|
+
|
45
|
+
# @return [Array<Resources>]
|
46
|
+
def perform_population
|
47
|
+
api.resource_all(stack)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'miasma'
|
2
|
+
|
3
|
+
module Miasma
|
4
|
+
module Models
|
5
|
+
class Orchestration
|
6
|
+
# Abstract server
|
7
|
+
class Stack < Types::Model
|
8
|
+
|
9
|
+
autoload :Resource, 'miasma/models/orchestration/resource'
|
10
|
+
autoload :Resources, 'miasma/models/orchestration/resources'
|
11
|
+
autoload :Event, 'miasma/models/orchestration/event'
|
12
|
+
autoload :Events, 'miasma/models/orchestration/events'
|
13
|
+
|
14
|
+
include Miasma::Utils::Memoization
|
15
|
+
|
16
|
+
# Stack output
|
17
|
+
class Output < Types::Data
|
18
|
+
|
19
|
+
attribute :key, String, :required => true
|
20
|
+
attribute :value, String, :required => true
|
21
|
+
attribute :description, String
|
22
|
+
|
23
|
+
attr_reader :stack
|
24
|
+
|
25
|
+
def initialize(stack, args={})
|
26
|
+
@stack = stack
|
27
|
+
super args
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
attribute :name, String, :required => true
|
33
|
+
attribute :description, String
|
34
|
+
attribute :state, Symbol, :allowed => Orchestration::VALID_RESOURCE_STATES, :coerce => lambda{|v| v.to_sym}
|
35
|
+
attribute :outputs, Output, :coerce => lambda{|v, stack| Output.new(stack, v) }, :multiple => true
|
36
|
+
attribute :status, String
|
37
|
+
attribute :status_reason, String
|
38
|
+
attribute :creation_time, Time, :coerce => lambda{|v| Time.parse(v.to_s)}
|
39
|
+
attribute :updated_time, Time, :coerce => lambda{|v| Time.parse(v.to_s)}
|
40
|
+
attribute :parameters, Smash, :coerce => lambda{|v| v.to_smash }
|
41
|
+
attribute :template, Smash, :depends => :perform_template_load, :coerce => lambda{|v| v = MultiJson.load(v) if v.is_a?(String); v.to_smash }
|
42
|
+
attribute :template_url, String
|
43
|
+
attribute :template_description, String
|
44
|
+
attribute :timeout_in_minutes, Integer
|
45
|
+
attribute :disable_rollback, [TrueClass, FalseClass]
|
46
|
+
attribute :notification_topics, String, :multiple => true
|
47
|
+
attribute :capabilities, String, :multiple => true
|
48
|
+
|
49
|
+
on_missing :reload
|
50
|
+
|
51
|
+
# Overload the loader so we can extract resources,
|
52
|
+
# events, and outputs
|
53
|
+
def load_data(args={})
|
54
|
+
args = args.to_smash
|
55
|
+
@resources = (args.delete(:resources) || []).each do |r|
|
56
|
+
Resource.new(r)
|
57
|
+
end
|
58
|
+
@events = (args.delete(:events) || []).each do |e|
|
59
|
+
Event.new(e)
|
60
|
+
end
|
61
|
+
super args
|
62
|
+
end
|
63
|
+
|
64
|
+
# Validate the stack template
|
65
|
+
#
|
66
|
+
# @return [TrueClass]
|
67
|
+
# @raises [Miasma::Error::OrchestrationError::InvalidTemplate]
|
68
|
+
def validate
|
69
|
+
perform_template_validate
|
70
|
+
end
|
71
|
+
|
72
|
+
# Override to scrub custom caches
|
73
|
+
#
|
74
|
+
# @return [self]
|
75
|
+
def reload
|
76
|
+
clear_memoizations!
|
77
|
+
remove = data.keys.find_all do |k|
|
78
|
+
![:id, :name].include?(k.to_sym)
|
79
|
+
end
|
80
|
+
remove.each do |k|
|
81
|
+
data.delete(k)
|
82
|
+
end
|
83
|
+
super
|
84
|
+
end
|
85
|
+
|
86
|
+
# @return [Events]
|
87
|
+
def events
|
88
|
+
memoize(:events) do
|
89
|
+
Events.new(self)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# @return [Resources]
|
94
|
+
def resources
|
95
|
+
memoize(:resources) do
|
96
|
+
Resources.new(self)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Always perform save. Remove dirty check
|
101
|
+
# provided by default.
|
102
|
+
def save
|
103
|
+
perform_save
|
104
|
+
end
|
105
|
+
|
106
|
+
protected
|
107
|
+
|
108
|
+
# Proxy save action up to the API
|
109
|
+
def perform_save
|
110
|
+
api.stack_save(self)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Proxy reload action up to the API
|
114
|
+
def perform_reload
|
115
|
+
api.stack_reload(self)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Proxy destroy action up to the API
|
119
|
+
def perform_destroy
|
120
|
+
api.stack_destroy(self)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Proxy validate action up to API
|
124
|
+
def perform_template_validate
|
125
|
+
error = api.stack_template_validate(self)
|
126
|
+
if(error)
|
127
|
+
raise Error::OrchestrationError::InvalidTemplate.new(error)
|
128
|
+
end
|
129
|
+
true
|
130
|
+
end
|
131
|
+
|
132
|
+
# Proxy template loading up to the API
|
133
|
+
def perform_template_load
|
134
|
+
memoize(:template) do
|
135
|
+
self.data[:template] = api.stack_template_load(self)
|
136
|
+
true
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'miasma'
|
2
|
+
|
3
|
+
module Miasma
|
4
|
+
module Models
|
5
|
+
class Orchestration
|
6
|
+
|
7
|
+
# Abstract stack collection
|
8
|
+
class Stacks < Types::Collection
|
9
|
+
|
10
|
+
# Locate stack by name or ID
|
11
|
+
#
|
12
|
+
# @param ident [String, Numeric] name or ID
|
13
|
+
# @return [Stack]
|
14
|
+
def get(ident)
|
15
|
+
all.detect do |stack|
|
16
|
+
stack.id.to_s == ident.to_s ||
|
17
|
+
stack.name.to_s == ident.to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return stacks matching given filter
|
22
|
+
#
|
23
|
+
# @param options [Hash] filter options
|
24
|
+
# @option options [String] :state current stack state
|
25
|
+
# @return [Array<Stack>]
|
26
|
+
def filter(options={})
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Stack] collection items class
|
31
|
+
def model
|
32
|
+
Stack
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
# @return [Array<Stack>]
|
38
|
+
def perform_population
|
39
|
+
api.stack_all
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
File without changes
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'miasma'
|
2
|
+
|
3
|
+
module Miasma
|
4
|
+
module Models
|
5
|
+
# Abstract storage API
|
6
|
+
class Storage < Types::Api
|
7
|
+
|
8
|
+
# Storage buckets
|
9
|
+
#
|
10
|
+
# @param filter [Hash] filtering options
|
11
|
+
# @return [Types::Collection<Models::Storage::Bucket>] buckets
|
12
|
+
def buckets(args={})
|
13
|
+
Buckets.new(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Create a new bucket
|
17
|
+
#
|
18
|
+
# @param bucket [Models::Storage::Bucket]
|
19
|
+
# @return [Models::Storage::Bucket]
|
20
|
+
def bucket_create(bucket)
|
21
|
+
raise NotImplementedError
|
22
|
+
end
|
23
|
+
|
24
|
+
# Destroy bucket
|
25
|
+
#
|
26
|
+
# @param bucket [Models::Storage::Bucket]
|
27
|
+
# @return [TrueClass, FalseClass]
|
28
|
+
def bucket_delete(bucket)
|
29
|
+
raise NotImplementedError
|
30
|
+
end
|
31
|
+
|
32
|
+
# Rename bucket
|
33
|
+
#
|
34
|
+
# @param bucket [Models::Storage::Bucket]
|
35
|
+
# @param new_name [String]
|
36
|
+
# @return [Models::Storage::Bucket] new bucket with updated name
|
37
|
+
def bucket_rename(bucket, new_name)
|
38
|
+
raise NotImplementedError
|
39
|
+
end
|
40
|
+
|
41
|
+
# Return all buckets
|
42
|
+
#
|
43
|
+
# @return [Array<Models::Storage::Bucket>]
|
44
|
+
def bucket_all
|
45
|
+
raise NotImplementedError
|
46
|
+
end
|
47
|
+
|
48
|
+
# Return all files within bucket
|
49
|
+
#
|
50
|
+
# @param bucket [Bucket]
|
51
|
+
# @return [Array<File>]
|
52
|
+
def file_all(bucket)
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|