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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2 -0
  3. data/README.md +179 -0
  4. data/lib/miasma.rb +52 -0
  5. data/lib/miasma/contrib/aws.rb +390 -0
  6. data/lib/miasma/contrib/aws/auto_scale.rb +85 -0
  7. data/lib/miasma/contrib/aws/compute.rb +112 -0
  8. data/lib/miasma/contrib/aws/load_balancer.rb +185 -0
  9. data/lib/miasma/contrib/aws/orchestration.rb +338 -0
  10. data/lib/miasma/contrib/rackspace.rb +164 -0
  11. data/lib/miasma/contrib/rackspace/auto_scale.rb +84 -0
  12. data/lib/miasma/contrib/rackspace/compute.rb +104 -0
  13. data/lib/miasma/contrib/rackspace/load_balancer.rb +117 -0
  14. data/lib/miasma/contrib/rackspace/orchestration.rb +255 -0
  15. data/lib/miasma/error.rb +89 -0
  16. data/lib/miasma/models.rb +14 -0
  17. data/lib/miasma/models/auto_scale.rb +55 -0
  18. data/lib/miasma/models/auto_scale/group.rb +64 -0
  19. data/lib/miasma/models/auto_scale/groups.rb +34 -0
  20. data/lib/miasma/models/block_storage.rb +0 -0
  21. data/lib/miasma/models/compute.rb +70 -0
  22. data/lib/miasma/models/compute/server.rb +71 -0
  23. data/lib/miasma/models/compute/servers.rb +35 -0
  24. data/lib/miasma/models/dns.rb +0 -0
  25. data/lib/miasma/models/load_balancer.rb +55 -0
  26. data/lib/miasma/models/load_balancer/balancer.rb +72 -0
  27. data/lib/miasma/models/load_balancer/balancers.rb +34 -0
  28. data/lib/miasma/models/monitoring.rb +0 -0
  29. data/lib/miasma/models/orchestration.rb +127 -0
  30. data/lib/miasma/models/orchestration/event.rb +38 -0
  31. data/lib/miasma/models/orchestration/events.rb +64 -0
  32. data/lib/miasma/models/orchestration/resource.rb +79 -0
  33. data/lib/miasma/models/orchestration/resources.rb +55 -0
  34. data/lib/miasma/models/orchestration/stack.rb +144 -0
  35. data/lib/miasma/models/orchestration/stacks.rb +46 -0
  36. data/lib/miasma/models/queues.rb +0 -0
  37. data/lib/miasma/models/storage.rb +60 -0
  38. data/lib/miasma/models/storage/bucket.rb +36 -0
  39. data/lib/miasma/models/storage/buckets.rb +41 -0
  40. data/lib/miasma/models/storage/file.rb +45 -0
  41. data/lib/miasma/models/storage/files.rb +52 -0
  42. data/lib/miasma/types.rb +13 -0
  43. data/lib/miasma/types/api.rb +145 -0
  44. data/lib/miasma/types/collection.rb +116 -0
  45. data/lib/miasma/types/data.rb +53 -0
  46. data/lib/miasma/types/model.rb +118 -0
  47. data/lib/miasma/types/thin_model.rb +76 -0
  48. data/lib/miasma/utils.rb +12 -0
  49. data/lib/miasma/utils/animal_strings.rb +29 -0
  50. data/lib/miasma/utils/immutable.rb +36 -0
  51. data/lib/miasma/utils/lazy.rb +231 -0
  52. data/lib/miasma/utils/memoization.rb +55 -0
  53. data/lib/miasma/utils/smash.rb +149 -0
  54. data/lib/miasma/version.rb +4 -0
  55. data/miasma.gemspec +18 -0
  56. 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