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,11 +1,10 @@
1
- require 'miasma'
1
+ require "miasma"
2
2
 
3
3
  module Miasma
4
4
  module Models
5
5
  class LoadBalancer
6
6
  # Abstract balancer
7
7
  class Balancer < Types::Model
8
-
9
8
  class Server < Types::ThinModel
10
9
  model Miasma::Models::Compute::Server
11
10
  end
@@ -41,14 +40,14 @@ module Miasma
41
40
  attribute :name, String
42
41
  attribute :state, Symbol, :allowed_values => [:active, :pending, :terminated]
43
42
  attribute :status, String
44
- attribute :servers, Server, :multiple => true, :coerce => lambda{|v| Server.new(v)}
45
- attribute :public_addresses, Address, :multiple => true, :coerce => lambda{|v| Address.new(v)}
46
- attribute :private_addresses, Address, :multiple => true, :coerce => lambda{|v| Address.new(v)}
47
- attribute :health_check, HealthCheck, :coerce => lambda{|v| HealthCheck.new(v)}
48
- attribute :listeners, Listener, :coerce => lambda{|v| Listener.new(v)}, :multiple => true
49
- attribute :created, Time, :coerce => lambda{|v| Time.parse(v.to_s)}
50
- attribute :updated, Time, :coerce => lambda{|v| Time.parse(v.to_s)}
51
- attribute :server_states, ServerState, :multiple => true, :coerce => lambda{|v| ServerState.new(v)}
43
+ attribute :servers, Server, :multiple => true, :coerce => lambda { |v| Server.new(v) }
44
+ attribute :public_addresses, Address, :multiple => true, :coerce => lambda { |v| Address.new(v) }
45
+ attribute :private_addresses, Address, :multiple => true, :coerce => lambda { |v| Address.new(v) }
46
+ attribute :health_check, HealthCheck, :coerce => lambda { |v| HealthCheck.new(v) }
47
+ attribute :listeners, Listener, :coerce => lambda { |v| Listener.new(v) }, :multiple => true
48
+ attribute :created, Time, :coerce => lambda { |v| Time.parse(v.to_s) }
49
+ attribute :updated, Time, :coerce => lambda { |v| Time.parse(v.to_s) }
50
+ attribute :server_states, ServerState, :multiple => true, :coerce => lambda { |v| ServerState.new(v) }
52
51
 
53
52
  on_missing :reload
54
53
 
@@ -73,7 +72,6 @@ module Miasma
73
72
  def perform_destroy
74
73
  api.balancer_destroy(self)
75
74
  end
76
-
77
75
  end
78
76
  end
79
77
  end
@@ -1,4 +1,4 @@
1
- require 'miasma'
1
+ require "miasma"
2
2
 
3
3
  module Miasma
4
4
  module Models
@@ -11,7 +11,7 @@ module Miasma
11
11
  #
12
12
  # @param options [Hash] filter options
13
13
  # @return [Array<Balancer>]
14
- def filter(options={})
14
+ def filter(options = {})
15
15
  raise NotImplementedError
16
16
  end
17
17
 
@@ -26,9 +26,7 @@ module Miasma
26
26
  def perform_population
27
27
  api.balancer_all
28
28
  end
29
-
30
29
  end
31
-
32
30
  end
33
31
  end
34
32
  end
@@ -1,12 +1,11 @@
1
- require 'miasma'
1
+ require "miasma"
2
2
 
3
3
  module Miasma
4
4
  module Models
5
5
  # Abstract orchestration API
6
6
  class Orchestration < Types::Api
7
-
8
- autoload :Stack, 'miasma/models/orchestration/stack'
9
- autoload :Stacks, 'miasma/models/orchestration/stacks'
7
+ autoload :Stack, "miasma/models/orchestration/stack"
8
+ autoload :Stacks, "miasma/models/orchestration/stacks"
10
9
 
11
10
  # @return [Smash] mapping of remote type to internal type
12
11
  RESOURCE_MAPPING = Smash.new
@@ -26,14 +25,14 @@ module Miasma
26
25
  :rollback_complete, :rollback_in_progress, :rollback_failed,
27
26
  :update_complete, :update_in_progress, :update_failed,
28
27
  :update_rollback_complete, :update_rollback_in_progress,
29
- :update_rollback_failed, :unknown
28
+ :update_rollback_failed, :unknown,
30
29
  ]
31
30
 
32
31
  # Orchestration stacks
33
32
  #
34
33
  # @param filter [Hash] filtering options
35
34
  # @return [Types::Collection<Models::Orchestration::Stack>] stacks
36
- def stacks(args={})
35
+ def stacks(args = {})
37
36
  memoize(:stacks) do
38
37
  Stacks.new(self)
39
38
  end
@@ -67,7 +66,7 @@ module Miasma
67
66
  #
68
67
  # @param options [Hash] filter
69
68
  # @return [Array<Models::Orchestration::Stack>]
70
- def stack_all(options={})
69
+ def stack_all(options = {})
71
70
  raise NotImplementedError
72
71
  end
73
72
 
@@ -87,6 +86,22 @@ module Miasma
87
86
  raise NotImplementedError
88
87
  end
89
88
 
89
+ # Plan stack update
90
+ #
91
+ # @param stack [Stack]
92
+ # @return [Plan]
93
+ def stack_plan(stack)
94
+ raise NotImplementedError
95
+ end
96
+
97
+ # Load plan for stack
98
+ #
99
+ # @param stack [Stack]
100
+ # @return [Plan]
101
+ def stack_plan_load(stack)
102
+ raise NotImplementedError
103
+ end
104
+
90
105
  # Return all resources for stack
91
106
  #
92
107
  # @param stack [Models::Orchestration::Stack]
@@ -127,6 +142,21 @@ module Miasma
127
142
  raise NotImplementedError
128
143
  end
129
144
 
145
+ # Return all plans for stack
146
+ #
147
+ # @param stack [Models::Orchestration::Stack]
148
+ # @return [Array<Models::Orchestration::Stack::Plan>]
149
+ def stack_plan_all(stack)
150
+ raise NotImplementedError
151
+ end
152
+
153
+ # Reload the plan data from the API
154
+ #
155
+ # @param plan [Models::Orchestration::Stack::Plan]
156
+ # @return [Models::Orchestration::Stack::Plan]
157
+ def stack_plan_reload(plan)
158
+ raise NotImplementedError
159
+ end
130
160
  end
131
161
  end
132
162
  end
@@ -1,4 +1,4 @@
1
- require 'miasma'
1
+ require "miasma"
2
2
 
3
3
  module Miasma
4
4
  module Models
@@ -7,7 +7,6 @@ module Miasma
7
7
 
8
8
  # Stack event
9
9
  class Event < Types::Model
10
-
11
10
  attribute :time, Time, :required => true
12
11
  attribute :resource_id, [String, Numeric], :required => true
13
12
  attribute :resource_logical_id, [String, Numeric]
@@ -18,7 +17,7 @@ module Miasma
18
17
 
19
18
  attr_reader :stack
20
19
 
21
- def initialize(stack, args={})
20
+ def initialize(stack, args = {})
22
21
  @stack = stack
23
22
  super stack.api, args
24
23
  end
@@ -29,9 +28,7 @@ module Miasma
29
28
  end
30
29
 
31
30
  include Utils::Immutable
32
-
33
31
  end
34
-
35
32
  end
36
33
  end
37
34
  end
@@ -1,4 +1,4 @@
1
- require 'miasma'
1
+ require "miasma"
2
2
 
3
3
  module Miasma
4
4
  module Models
@@ -23,7 +23,7 @@ module Miasma
23
23
  #
24
24
  # @param options [Hash] filter options
25
25
  # @return [Array<Event>]
26
- def filter(options={})
26
+ def filter(options = {})
27
27
  raise NotImplementedError
28
28
  end
29
29
 
@@ -31,7 +31,7 @@ module Miasma
31
31
  #
32
32
  # @param args [Hash] creation options
33
33
  # @return [Event]
34
- def build(args={})
34
+ def build(args = {})
35
35
  Event.new(stack, args.to_smash)
36
36
  end
37
37
 
@@ -44,9 +44,9 @@ module Miasma
44
44
  #
45
45
  # @return [Array<Event>] new events fetched
46
46
  def update!
47
- if(memoized?(:collection))
47
+ if memoized?(:collection)
48
48
  current_events = all
49
- if(api.respond_to?(:event_all_new))
49
+ if api.respond_to?(:event_all_new)
50
50
  new_events = api.event_all_new(self)
51
51
  unmemoize(:collection)
52
52
  memoize(:collection) do
@@ -67,9 +67,7 @@ module Miasma
67
67
  def perform_population
68
68
  api.event_all(stack)
69
69
  end
70
-
71
70
  end
72
-
73
71
  end
74
72
  end
75
73
  end
@@ -0,0 +1,87 @@
1
+ require "miasma"
2
+
3
+ module Miasma
4
+ module Models
5
+ class Orchestration
6
+ class Stack
7
+ # Stack update plan
8
+ class Plan < Types::Model
9
+ attr_reader :stack
10
+
11
+ def initialize(stack, args = {})
12
+ @stack = stack
13
+ super stack.api, args
14
+ end
15
+
16
+ class Diff < Types::Data
17
+ attribute :name, String, :required => true
18
+ attribute :current, String, :required => true
19
+ attribute :proposed, String, :required => true
20
+ end
21
+
22
+ # Plan item
23
+ class Item < Types::Data
24
+ attribute :name, String, :required => true
25
+ attribute :type, String, :required => true
26
+ attribute :diffs, Diff, :multiple => true
27
+ end
28
+
29
+ attribute :name, String, :coerce => lambda { |x| x.to_s }
30
+ attribute :add, Item, :multiple => true
31
+ attribute :remove, Item, :multiple => true
32
+ attribute :replace, Item, :multiple => true
33
+ attribute :interrupt, Item, :multiple => true
34
+ attribute :unavailable, Item, :multiple => true
35
+ attribute :unknown, Item, :multiple => true
36
+ attribute :stacks, Smash
37
+ attribute :state, String, :coerce => lambda { |x| x.to_s }
38
+ attribute :parameters, Smash, :default => Smash.new
39
+ attribute :template, Smash, :default => Smash.new
40
+ attribute :created_at, Time, :coerce => lambda { |x| Time.parse(x.to_s) }
41
+
42
+ DIFF_ATTRIBUTES = [
43
+ :add, :remove, :replace, :interrupt, :unavailable, :unknown,
44
+ ]
45
+
46
+ # Plan has no modifications
47
+ #
48
+ # @return [TrueClass, FalseClass]
49
+ def empty?
50
+ DIFF_ATTRIBUTES.all? { |attr|
51
+ self.send(attr).empty?
52
+ } && stacks.values.all? { |stk| stk.empty? }
53
+ end
54
+
55
+ # Execute this stack plan
56
+ #
57
+ # @return [Stack]
58
+ def execute!
59
+ if self == stack.plan
60
+ stack.plan_execute
61
+ else
62
+ raise Error::OrchestrationError::InvalidStackPlan.new "Plan is no longer valid for linked stack."
63
+ end
64
+ stack.reload
65
+ end
66
+
67
+ # Destroy this stack plan
68
+ #
69
+ # @return [Stack]
70
+ def destroy
71
+ if self == stack.plan
72
+ stack.plan_destroy
73
+ else
74
+ raise Error::OrchestrationError::InvalidStackPlan.new "Plan is no longer valid for linked stack."
75
+ end
76
+ stack.reload
77
+ end
78
+
79
+ # Proxy reload action up to the API
80
+ def perform_reload
81
+ api.stack_plan_reload(self)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,52 @@
1
+ require "miasma"
2
+
3
+ module Miasma
4
+ module Models
5
+ class Orchestration
6
+ class Stack
7
+ # Abstract stack plans collection
8
+ class Plans < Types::Collection
9
+
10
+ # @return [Miasma::Models::Orchestration::Stack]
11
+ attr_reader :stack
12
+
13
+ # Override to capture originating stack
14
+ #
15
+ # @param stack [Stack]
16
+ def initialize(stack)
17
+ @stack = stack
18
+ super stack.api
19
+ end
20
+
21
+ # Return plans matching given filter
22
+ #
23
+ # @param options [Hash] filter options
24
+ # @return [Array<Plans>]
25
+ def filter(options = {})
26
+ raise NotImplementedError
27
+ end
28
+
29
+ # Build a new plan instance
30
+ #
31
+ # @param args [Hash] creation options
32
+ # @return [Plan]
33
+ def build(args = {})
34
+ Plan.new(stack, args.to_smash)
35
+ end
36
+
37
+ # @return [Plan] collection item class
38
+ def model
39
+ Plan
40
+ end
41
+
42
+ protected
43
+
44
+ # @return [Array<Plan>]
45
+ def perform_population
46
+ api.stack_plan_all(stack)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,4 +1,4 @@
1
- require 'miasma'
1
+ require "miasma"
2
2
 
3
3
  module Miasma
4
4
  module Models
@@ -7,20 +7,19 @@ module Miasma
7
7
 
8
8
  # Stack resource
9
9
  class Resource < Types::Model
10
-
11
10
  attribute :name, String, :required => true
12
11
  attribute :type, String, :required => true
13
12
  attribute :logical_id, [String, Numeric]
14
13
  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}
14
+ attribute :status, [String, Symbol], :required => true, :coerce => lambda { |v| v.to_s.to_sym }
16
15
  attribute :status_reason, String
17
- attribute :updated, Time, :coerce => lambda{|v| Time.parse(v.to_s)}
16
+ attribute :updated, Time, :coerce => lambda { |v| Time.parse(v.to_s) }
18
17
 
19
18
  on_missing :reload
20
19
 
21
20
  attr_reader :stack
22
21
 
23
- def initialize(stack, args={})
22
+ def initialize(stack, args = {})
24
23
  @stack = stack
25
24
  super stack.api, args
26
25
  end
@@ -28,15 +27,15 @@ module Miasma
28
27
  # @return [Miasma::Types::Model] provides mapped resource class
29
28
  def dereference
30
29
  # Insert provider to namespace
31
- provider_const = self.class.name.split('::').insert(3, Utils.camel(api.provider))
30
+ provider_const = self.class.name.split("::").insert(3, Utils.camel(api.provider))
32
31
  provider_const.slice!(-2, 2)
33
32
  # Insert mapping constant name and fetch
34
- const = provider_const.push(:RESOURCE_MAPPING).inject(Object) do |memo, konst|
33
+ const = provider_const.push(:RESOURCE_MAPPING).inject(Object) do |memo, konst|
35
34
  res = memo.const_get(konst)
36
35
  break unless res
37
36
  res
38
37
  end
39
- unless(const[self.type])
38
+ unless const[self.type]
40
39
  raise KeyError.new "Failed to locate requested mapping! (`#{self.type}`)"
41
40
  end
42
41
  const[self.type]
@@ -49,6 +48,7 @@ module Miasma
49
48
  info = dereference
50
49
  api.api_for(info[:api]).send(info[:collection]).get(self.id)
51
50
  end
51
+
52
52
  alias_method :instance, :expand
53
53
 
54
54
  # Proxy reload action up to the API
@@ -72,9 +72,7 @@ module Miasma
72
72
  end
73
73
 
74
74
  include Utils::Immutable
75
-
76
75
  end
77
-
78
76
  end
79
77
  end
80
78
  end
@@ -1,4 +1,4 @@
1
- require 'miasma'
1
+ require "miasma"
2
2
 
3
3
  module Miasma
4
4
  module Models
@@ -23,7 +23,7 @@ module Miasma
23
23
  #
24
24
  # @param options [Hash] filter options
25
25
  # @return [Array<Resources>]
26
- def filter(options={})
26
+ def filter(options = {})
27
27
  raise NotImplementedError
28
28
  end
29
29
 
@@ -31,7 +31,7 @@ module Miasma
31
31
  #
32
32
  # @param args [Hash] creation options
33
33
  # @return [Resource]
34
- def build(args={})
34
+ def build(args = {})
35
35
  Resource.new(stack, args.to_smash)
36
36
  end
37
37
 
@@ -46,9 +46,7 @@ module Miasma
46
46
  def perform_population
47
47
  api.resource_all(stack)
48
48
  end
49
-
50
49
  end
51
-
52
50
  end
53
51
  end
54
52
  end