miasma 0.3.2 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
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