miasma 0.3.2 → 0.3.4

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 (58) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +4 -0
  3. data/LICENSE +1 -1
  4. data/README.md +5 -2
  5. data/lib/miasma.rb +14 -15
  6. data/lib/miasma/error.rb +17 -10
  7. data/lib/miasma/models.rb +9 -9
  8. data/lib/miasma/models/auto_scale.rb +5 -7
  9. data/lib/miasma/models/auto_scale/group.rb +8 -13
  10. data/lib/miasma/models/auto_scale/groups.rb +2 -4
  11. data/lib/miasma/models/block_storage.rb +1 -0
  12. data/lib/miasma/models/compute.rb +4 -6
  13. data/lib/miasma/models/compute/server.rb +5 -6
  14. data/lib/miasma/models/compute/servers.rb +2 -4
  15. data/lib/miasma/models/dns.rb +1 -0
  16. data/lib/miasma/models/load_balancer.rb +5 -7
  17. data/lib/miasma/models/load_balancer/balancer.rb +9 -11
  18. data/lib/miasma/models/load_balancer/balancers.rb +2 -4
  19. data/lib/miasma/models/monitoring.rb +1 -0
  20. data/lib/miasma/models/orchestration.rb +37 -7
  21. data/lib/miasma/models/orchestration/event.rb +2 -5
  22. data/lib/miasma/models/orchestration/events.rb +5 -7
  23. data/lib/miasma/models/orchestration/plan.rb +87 -0
  24. data/lib/miasma/models/orchestration/plans.rb +52 -0
  25. data/lib/miasma/models/orchestration/resource.rb +8 -10
  26. data/lib/miasma/models/orchestration/resources.rb +3 -5
  27. data/lib/miasma/models/orchestration/stack.rb +106 -20
  28. data/lib/miasma/models/orchestration/stacks.rb +3 -5
  29. data/lib/miasma/models/queues.rb +1 -0
  30. data/lib/miasma/models/queuing.rb +72 -0
  31. data/lib/miasma/models/queuing/queue.rb +77 -0
  32. data/lib/miasma/models/queuing/queues.rb +32 -0
  33. data/lib/miasma/models/storage.rb +8 -9
  34. data/lib/miasma/models/storage/bucket.rb +4 -7
  35. data/lib/miasma/models/storage/buckets.rb +2 -4
  36. data/lib/miasma/models/storage/file.rb +13 -16
  37. data/lib/miasma/models/storage/files.rb +3 -5
  38. data/lib/miasma/specs.rb +4 -4
  39. data/lib/miasma/specs/compute_abstract.rb +24 -33
  40. data/lib/miasma/specs/load_balancer_abstract.rb +17 -27
  41. data/lib/miasma/specs/orchestration_abstract.rb +26 -37
  42. data/lib/miasma/specs/storage_abstract.rb +21 -27
  43. data/lib/miasma/types.rb +6 -8
  44. data/lib/miasma/types/api.rb +28 -31
  45. data/lib/miasma/types/collection.rb +8 -10
  46. data/lib/miasma/types/data.rb +2 -5
  47. data/lib/miasma/types/model.rb +13 -16
  48. data/lib/miasma/types/thin_model.rb +7 -10
  49. data/lib/miasma/utils.rb +7 -7
  50. data/lib/miasma/utils/animal_strings.rb +1 -3
  51. data/lib/miasma/utils/api_methoding.rb +2 -5
  52. data/lib/miasma/utils/immutable.rb +2 -6
  53. data/lib/miasma/utils/lazy.rb +2 -2
  54. data/lib/miasma/utils/memoization.rb +1 -1
  55. data/lib/miasma/utils/smash.rb +1 -1
  56. data/lib/miasma/version.rb +1 -1
  57. data/miasma.gemspec +21 -19
  58. metadata +44 -12
@@ -1,4 +1,4 @@
1
- require 'miasma'
1
+ require "miasma"
2
2
 
3
3
  module Miasma
4
4
  module Models
@@ -6,57 +6,64 @@ module Miasma
6
6
  # Abstract server
7
7
  class Stack < Types::Model
8
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'
9
+ # Stack states which are valid to execute update plan
10
+ VALID_PLAN_STATES = [
11
+ :create_complete, :update_complete, :update_failed,
12
+ :rollback_complete, :rollback_failed, :unknown,
13
+ ]
14
+
15
+ autoload :Resource, "miasma/models/orchestration/resource"
16
+ autoload :Resources, "miasma/models/orchestration/resources"
17
+ autoload :Event, "miasma/models/orchestration/event"
18
+ autoload :Events, "miasma/models/orchestration/events"
19
+ autoload :Plan, "miasma/models/orchestration/plan"
20
+ autoload :Plans, "miasma/models/orchestration/plans"
13
21
 
14
22
  include Miasma::Utils::Memoization
15
23
 
16
24
  # Stack output
17
25
  class Output < Types::Data
18
-
19
26
  attribute :key, String, :required => true
20
27
  attribute :value, String, :required => true
21
28
  attribute :description, String
22
29
 
23
30
  attr_reader :stack
24
31
 
25
- def initialize(stack, args={})
32
+ def initialize(stack, args = {})
26
33
  @stack = stack
27
34
  super args
28
35
  end
29
-
30
36
  end
31
37
 
32
38
  attribute :name, String, :required => true
33
39
  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
40
+ attribute :state, Symbol, :allowed => Orchestration::VALID_RESOURCE_STATES, :coerce => lambda { |v| v.to_sym }
41
+ attribute :outputs, Output, :coerce => lambda { |v, stack| Output.new(stack, v) }, :multiple => true
36
42
  attribute :status, String
37
43
  attribute :status_reason, String
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
- 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 }
44
+ attribute :created, Time, :coerce => lambda { |v| Time.parse(v.to_s) }
45
+ attribute :updated, Time, :coerce => lambda { |v| Time.parse(v.to_s) }
46
+ attribute :parameters, Smash, :coerce => lambda { |v| v.to_smash }
47
+ attribute :template, Smash, :depends => :perform_template_load, :coerce => lambda { |v| v = MultiJson.load(v) if v.is_a?(String); v.to_smash }
42
48
  attribute :template_url, String
43
49
  attribute :template_description, String
44
50
  attribute :timeout_in_minutes, Integer
45
- attribute :tags, Smash, :coerce => lambda{|v| v.to_smash}
51
+ attribute :tags, Smash, :coerce => lambda { |v| v.to_smash }, :default => Smash.new
46
52
  # TODO: This is new in AWS but I like this better for the
47
53
  # attribute. For now, keep both but i would like to deprecate
48
54
  # out the disable_rollback and provide the same functionality
49
55
  # via this attribute.
50
- attribute :on_failure, String, :allowed => %w(nothing rollback delete), :coerce => lambda{|v| v.to_s.downcase}
56
+ attribute :on_failure, String, :allowed => %w(nothing rollback delete), :coerce => lambda { |v| v.to_s.downcase }
51
57
  attribute :disable_rollback, [TrueClass, FalseClass]
52
58
  attribute :notification_topics, String, :multiple => true
53
59
  attribute :capabilities, String, :multiple => true
60
+ attribute :plan, Plan, :depends => :load_plan
54
61
 
55
62
  on_missing :reload
56
63
 
57
64
  # Overload the loader so we can extract resources,
58
65
  # events, and outputs
59
- def load_data(args={})
66
+ def load_data(args = {})
60
67
  args = args.to_smash
61
68
  @resources = (args.delete(:resources) || []).each do |r|
62
69
  Resource.new(r)
@@ -75,6 +82,45 @@ module Miasma
75
82
  perform_template_validate
76
83
  end
77
84
 
85
+ # Create a new stack plan
86
+ #
87
+ # @return [Plan]
88
+ def plan_generate
89
+ if plan
90
+ raise Miasma::Error::OrchestrationError::StackPlanExists.new(
91
+ "Plan already exists for this stack"
92
+ )
93
+ else
94
+ perform_plan
95
+ end
96
+ end
97
+
98
+ # Execute current execute
99
+ #
100
+ # @return [self]
101
+ def plan_execute
102
+ if dirty?(:plan)
103
+ perform_plan_execute
104
+ else
105
+ raise Miasma::Error::OrchestrationError::InvalidStackPlan.new(
106
+ "This stack instance does not have a generated plan"
107
+ )
108
+ end
109
+ end
110
+
111
+ # Delete the current plan
112
+ #
113
+ # @return [self]
114
+ def plan_destroy
115
+ if dirty?(:plan)
116
+ perform_plan_destroy
117
+ else
118
+ raise Miasma::Error::OrchestrationError::InvalidStackPlan.new(
119
+ "This stack instance does not have a generated plan"
120
+ )
121
+ end
122
+ end
123
+
78
124
  # Override to scrub custom caches
79
125
  #
80
126
  # @return [self]
@@ -96,6 +142,13 @@ module Miasma
96
142
  end
97
143
  end
98
144
 
145
+ # @return [Plans]
146
+ def plans
147
+ memoize(:plans) do
148
+ Plans.new(self)
149
+ end
150
+ end
151
+
99
152
  # @return [Resources]
100
153
  def resources
101
154
  memoize(:resources) do
@@ -111,6 +164,41 @@ module Miasma
111
164
 
112
165
  protected
113
166
 
167
+ # Stack is in valid state to generate plan
168
+ #
169
+ # @return [TrueClass, FalseClass]
170
+ def planable?
171
+ state.nil? || VALID_PLAN_STATES.include?(state)
172
+ end
173
+
174
+ # Proxy load plan action up to the API
175
+ def load_plan
176
+ memoize(:plan) do
177
+ api.stack_plan_load(self)
178
+ end
179
+ end
180
+
181
+ # Proxy plan action up to the API
182
+ def perform_plan
183
+ if planable?
184
+ api.stack_plan(self)
185
+ else
186
+ raise Error::OrchestrationError::InvalidPlanState.new(
187
+ "Stack state `#{state}` is not valid for plan generation"
188
+ )
189
+ end
190
+ end
191
+
192
+ # Proxy plan execute action up to the API
193
+ def perform_plan_execute
194
+ api.stack_plan_execute(self)
195
+ end
196
+
197
+ # Proxy plan delete action up to the API
198
+ def perform_plan_destroy
199
+ api.stack_plan_destroy(self)
200
+ end
201
+
114
202
  # Proxy save action up to the API
115
203
  def perform_save
116
204
  api.stack_save(self)
@@ -129,7 +217,7 @@ module Miasma
129
217
  # Proxy validate action up to API
130
218
  def perform_template_validate
131
219
  error = api.stack_template_validate(self)
132
- if(error)
220
+ if error
133
221
  raise Error::OrchestrationError::InvalidTemplate.new(error)
134
222
  end
135
223
  true
@@ -142,9 +230,7 @@ module Miasma
142
230
  true
143
231
  end
144
232
  end
145
-
146
233
  end
147
-
148
234
  end
149
235
  end
150
236
  end
@@ -1,4 +1,4 @@
1
- require 'miasma'
1
+ require "miasma"
2
2
 
3
3
  module Miasma
4
4
  module Models
@@ -12,7 +12,7 @@ module Miasma
12
12
  # @param options [Hash] filter options
13
13
  # @option options [String] :state current stack state
14
14
  # @return [Array<Stack>]
15
- def filter(options={})
15
+ def filter(options = {})
16
16
  raise NotImplementedError
17
17
  end
18
18
 
@@ -30,15 +30,13 @@ module Miasma
30
30
 
31
31
  # @return [Stack]
32
32
  def perform_get(ident)
33
- if(api.respond_to?(:stack_get))
33
+ if api.respond_to?(:stack_get)
34
34
  api.stack_get(ident)
35
35
  else
36
36
  super
37
37
  end
38
38
  end
39
-
40
39
  end
41
-
42
40
  end
43
41
  end
44
42
  end
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,72 @@
1
+ require "miasma"
2
+
3
+ module Miasma
4
+ module Models
5
+ # Abstract queue API
6
+ class Queuing < Types::API
7
+ autoload :Queue, "miasma/models/queuing/queue"
8
+ autoload :Queues, "miasma/models/queuing/queues"
9
+
10
+ # Queues
11
+ #
12
+ # @param filter [Hash] filtering options
13
+ # @return [Types::Collections<Models::Queuing::Queue>] queues
14
+ def queues(filter = {})
15
+ memoize(:queues) do
16
+ Queues.new(self)
17
+ end
18
+ end
19
+
20
+ # Save the queue
21
+ #
22
+ # @param queue [Models::Queuing::Queue]
23
+ # @return [Models::Queuing::Queue]
24
+ def queue_save(queue)
25
+ raise NotImplementedError
26
+ end
27
+
28
+ # Reload the queue data from the API
29
+ #
30
+ # @param queue [Models::Queuing::Queue]
31
+ # @return [Models::Queuing::Queue]
32
+ def queue_reload(queue)
33
+ raise NotImplementedError
34
+ end
35
+
36
+ # Delete the queue
37
+ #
38
+ # @param queue [Models::Queuing::Queue]
39
+ # @return [TrueClass, FalseClass]
40
+ def queue_destroy(queue)
41
+ raise NotImplementedError
42
+ end
43
+
44
+ # Return all queues
45
+ #
46
+ # @param options [Hash] filter
47
+ # @return [Array<Models::Queuing::Queue>]
48
+ def queue_all(options = {})
49
+ raise NotImplementedError
50
+ end
51
+
52
+ # Deliver message(s) to queue
53
+ #
54
+ # @param queue [Models::Queuing::Queue]
55
+ # @param msg_or_msgs [String, Array<String>] message(s) to deliver
56
+ # @param options [Hash] delivery options
57
+ # @return [Receipt]
58
+ def queue_deliver(queue, msg_or_msgs, options = {})
59
+ raise NotImplementedError
60
+ end
61
+
62
+ # Receive message(s) from queue
63
+ #
64
+ # @param queue [Models::Queuing::Queue]
65
+ # @param options [Hash] delivery options
66
+ # @return [Queue::Message, Array<Queue::Message>]
67
+ def queue_receive(queue, options = {})
68
+ raise NotImplementedError
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,77 @@
1
+ require "miasma"
2
+
3
+ module Miasma
4
+ module Models
5
+ class Queuing
6
+ # Abstract balancer
7
+ class Queue < Types::Model
8
+ class Message < Types::Data
9
+ attribute :origin, Queue, :required => true
10
+ attribute :content, String, :required => true
11
+ attribute :created, Time
12
+ attribute :updated, Time
13
+ attribute :timeout, Integer
14
+ end
15
+
16
+ class Receipt < Types::Data
17
+ attribute :message, String, :required => true
18
+ attribute :checksum, String
19
+ end
20
+
21
+ attribute :name, String, :required => true
22
+ attribute :created, Time, :required => true
23
+ attribute :updated, Time
24
+ attribute :maximum_message_size, Integer
25
+ attribute :messages_available, Integer
26
+
27
+ on_missing :reload
28
+
29
+ # Deliver message(s) to the queue
30
+ #
31
+ # @param msg_or_msgs [String, Array<String>]
32
+ # @param options [Hash]
33
+ # @return [Array<Receipt>]
34
+ def deliver(msg_or_msgs, options = {})
35
+ result = perform_delivery(msg_or_msgs, options)
36
+ result.is_a?(Array) ? result : [result]
37
+ end
38
+
39
+ # Receive message(s) from the queue
40
+ #
41
+ # @param options [Hash]
42
+ # @return [Array<Message>]
43
+ def receive(options = {})
44
+ result = perform_receive(options)
45
+ result.is_a?(Array) ? result : [result]
46
+ end
47
+
48
+ protected
49
+
50
+ # Proxy delivery action up to the API
51
+ def perform_delivery(msg, options = {})
52
+ api.queue_deliver(self, msg, options)
53
+ end
54
+
55
+ # Proxy receive action up to the API
56
+ def perform_receive(options = {})
57
+ api.queue_receive(self, options)
58
+ end
59
+
60
+ # Proxy save action up to the API
61
+ def perform_save
62
+ api.queue_save(self)
63
+ end
64
+
65
+ # Proxy reload action up to the API
66
+ def perform_reload
67
+ api.queue_reload(self)
68
+ end
69
+
70
+ # Proxy destroy action up to the API
71
+ def perform_destroy
72
+ api.queue_destroy(self)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,32 @@
1
+ require "miasma"
2
+
3
+ module Miasma
4
+ module Models
5
+ class Queuing
6
+
7
+ # Abstract queues collection
8
+ class Queues < Types::Collection
9
+
10
+ # Return queues matching given filter
11
+ #
12
+ # @param options [Hash] filter options
13
+ # @return [Array<Queue>]
14
+ def filter(options = {})
15
+ raise NotImplementedError
16
+ end
17
+
18
+ # @return [Queue] collection item class
19
+ def model
20
+ Queue
21
+ end
22
+
23
+ protected
24
+
25
+ # @return [Array<Queue>]
26
+ def perform_population
27
+ api.queue_all
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,4 +1,4 @@
1
- require 'miasma'
1
+ require "miasma"
2
2
 
3
3
  module Miasma
4
4
  module Models
@@ -6,20 +6,20 @@ module Miasma
6
6
  class Storage < Types::Api
7
7
 
8
8
  # @return [Integer] max bytes allowed for storing body in string
9
- MAX_BODY_SIZE_FOR_STRINGIFY = (1024**2) * 10
9
+ MAX_BODY_SIZE_FOR_STRINGIFY = (1024 ** 2) * 10
10
10
  # @return [Integer] chunking size for reading IO
11
- READ_BODY_CHUNK_SIZE = (1024**2) * 5
11
+ READ_BODY_CHUNK_SIZE = (1024 ** 2) * 5
12
12
 
13
- autoload :Buckets, 'miasma/models/storage/buckets'
14
- autoload :Bucket, 'miasma/models/storage/bucket'
15
- autoload :Files, 'miasma/models/storage/files'
16
- autoload :File, 'miasma/models/storage/file'
13
+ autoload :Buckets, "miasma/models/storage/buckets"
14
+ autoload :Bucket, "miasma/models/storage/bucket"
15
+ autoload :Files, "miasma/models/storage/files"
16
+ autoload :File, "miasma/models/storage/file"
17
17
 
18
18
  # Storage buckets
19
19
  #
20
20
  # @param filter [Hash] filtering options
21
21
  # @return [Types::Collection<Models::Storage::Bucket>] buckets
22
- def buckets(args={})
22
+ def buckets(args = {})
23
23
  memoize(:buckets) do
24
24
  Buckets.new(self)
25
25
  end
@@ -87,7 +87,6 @@ module Miasma
87
87
  def file_reload(file)
88
88
  raise NotImplementedError
89
89
  end
90
-
91
90
  end
92
91
  end
93
92
  end