chef-provisioning 0.19 → 0.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +62 -32
  3. data/lib/chef/provider/load_balancer.rb +18 -8
  4. data/lib/chef/provider/machine.rb +11 -7
  5. data/lib/chef/provider/machine_batch.rb +8 -4
  6. data/lib/chef/provider/machine_execute.rb +1 -1
  7. data/lib/chef/provider/machine_image.rb +46 -14
  8. data/lib/chef/provisioning.rb +9 -1
  9. data/lib/chef/provisioning/chef_managed_entry_store.rb +128 -0
  10. data/lib/chef/provisioning/chef_run_data.rb +9 -16
  11. data/lib/chef/provisioning/convergence_strategy/install_cached.rb +25 -7
  12. data/lib/chef/provisioning/convergence_strategy/install_msi.rb +26 -8
  13. data/lib/chef/provisioning/convergence_strategy/install_sh.rb +28 -6
  14. data/lib/chef/provisioning/driver.rb +28 -21
  15. data/lib/chef/provisioning/load_balancer_spec.rb +6 -71
  16. data/lib/chef/provisioning/machine_image_spec.rb +34 -0
  17. data/lib/chef/provisioning/machine_spec.rb +23 -47
  18. data/lib/chef/provisioning/managed_entry.rb +121 -0
  19. data/lib/chef/provisioning/managed_entry_store.rb +136 -0
  20. data/lib/chef/provisioning/recipe_dsl.rb +0 -4
  21. data/lib/chef/provisioning/version.rb +1 -1
  22. data/lib/chef/resource/chef_data_bag_resource.rb +1 -2
  23. data/lib/chef/resource/load_balancer.rb +1 -0
  24. data/lib/chef/resource/machine.rb +1 -1
  25. data/lib/chef/resource/machine_batch.rb +2 -2
  26. data/lib/chef/resource/machine_execute.rb +2 -1
  27. metadata +7 -8
  28. data/lib/chef/provisioning/chef_image_spec.rb +0 -111
  29. data/lib/chef/provisioning/chef_load_balancer_spec.rb +0 -108
  30. data/lib/chef/provisioning/chef_machine_spec.rb +0 -83
  31. data/lib/chef/provisioning/image_spec.rb +0 -72
@@ -1,79 +1,14 @@
1
+ require 'chef/provisioning/managed_entry'
2
+
1
3
  class Chef
2
4
  module Provisioning
3
5
  #
4
- # Specification for a machine. Sufficient information to find and contact it
6
+ # Specification for a image. Sufficient information to find and contact it
5
7
  # after it has been set up.
6
8
  #
7
- # TODO: This is pretty similar to image_spec, generalize this.
8
- class LoadBalancerSpec
9
- def initialize(load_balancer_data)
10
- @load_balancer_data = load_balancer_data
11
- # Upgrade from metal to chef_provisioning ASAP.
12
- if @load_balancer_data['normal'] && !@load_balancer_data['normal']['chef_provisioning'] && @load_balancer_data['normal']['metal']
13
- @load_balancer_data['normal']['chef_provisioning'] = @load_balancer_data['normal'].delete('metal')
14
- end
15
- end
16
-
17
- attr_reader :load_balancer_data
18
- attr_reader :machines
19
-
20
- #
21
- # Globally unique identifier for this machine. Does not depend on the machine's
22
- # location or existence.
23
- #
24
- def id
25
- raise "id unimplemented"
26
- end
27
-
28
- #
29
- # Name of the machine. Corresponds to the name in "machine 'name' do" ...
30
- #
31
- def name
32
- load_balancer_data['id']
33
- end
34
-
35
- #
36
- # Location of this machine. This should be a freeform hash, with enough
37
- # information for the driver to look it up and create a Machine object to
38
- # access it.
39
- #
40
- # This MUST include a 'driver_url' attribute with the driver's URL in it.
41
- #
42
- # chef-provisioning will do its darnedest to not lose this information.
43
- #
44
- def location
45
- load_balancer_data['location']
46
- end
47
-
48
- #
49
- # Set the location for this machine.
50
- #
51
- def location=(value)
52
- load_balancer_data['location'] = value
53
- end
54
-
55
- # URL to the driver. Convenience for location['driver_url']
56
- def driver_url
57
- location ? location['driver_url'] : nil
58
- end
59
-
60
-
61
- def machines
62
- load_balancer_data['machines'] || []
63
- end
64
-
65
- def machines=(value)
66
- load_balancer_data['machines'] = value
67
- end
68
-
69
- #
70
- # Save this node to the server. If you have significant information that
71
- # could be lost, you should do this as quickly as possible. Data will be
72
- # saved automatically for you after allocate_machine and ready_machine.
73
- #
74
- def save(action_handler)
75
- raise "save unimplemented"
76
- end
9
+ class LoadBalancerSpec < ManagedEntry
10
+ alias :location :reference
11
+ alias :location= :reference=
77
12
  end
78
13
  end
79
14
  end
@@ -0,0 +1,34 @@
1
+ require 'chef/provisioning/managed_entry'
2
+
3
+ class Chef
4
+ module Provisioning
5
+ #
6
+ # Specification for a image. Sufficient information to find and contact it
7
+ # after it has been set up.
8
+ #
9
+ class MachineImageSpec < ManagedEntry
10
+ alias :location :reference
11
+ alias :location= :reference=
12
+
13
+ def from_image
14
+ data['from_image']
15
+ end
16
+ def from_image=(value)
17
+ data['from_image'] = value
18
+ end
19
+ def run_list
20
+ data['run_list']
21
+ end
22
+ def run_list=(value)
23
+ data['run_list'] = value
24
+ end
25
+ def machine_options
26
+ @machine_options
27
+ end
28
+ def machine_options=(value)
29
+ Chef::Log.warn("Machine options are no longer stored in machine_image_spec. Drivers that store machine_options will stop working with Provisioning 1.0.")
30
+ @machine_options = value
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,33 +1,26 @@
1
+ require 'chef/provisioning/managed_entry'
2
+
1
3
  class Chef
2
4
  module Provisioning
3
5
  #
4
6
  # Specification for a machine. Sufficient information to find and contact it
5
7
  # after it has been set up.
6
8
  #
7
- class MachineSpec
8
- def initialize(node)
9
- @node = node
9
+ class MachineSpec < ManagedEntry
10
+ def initialize(*args)
11
+ super
12
+ data['name'] ||= name
10
13
  # Upgrade from metal to chef_provisioning ASAP.
11
- if node['normal'] && !node['normal']['chef_provisioning'] && node['normal']['metal']
12
- node['normal']['chef_provisioning'] = node['normal'].delete('metal')
14
+ if data['normal'] && !data['normal']['chef_provisioning'] && data['normal']['metal']
15
+ data['normal']['chef_provisioning'] = data['normal'].delete('metal')
13
16
  end
14
17
  end
15
18
 
16
- attr_reader :node
17
-
18
- #
19
- # Globally unique identifier for this machine. Does not depend on the machine's
20
- # location or existence.
21
- #
22
- def id
23
- raise "id unimplemented"
24
- end
19
+ alias :node :data
25
20
 
26
- #
27
- # Name of the machine. Corresponds to the name in "machine 'name' do" ...
28
- #
29
- def name
30
- node['name']
21
+ def attrs
22
+ data['normal'] ||= {}
23
+ data['normal']['chef_provisioning'] ||= {}
31
24
  end
32
25
 
33
26
  #
@@ -39,43 +32,26 @@ module Provisioning
39
32
  #
40
33
  # chef-provisioning will do its darnedest to not lose this information.
41
34
  #
42
- def location
43
- chef_provisioning_attr('location')
35
+ def reference
36
+ attrs['reference'] || attrs['location']
44
37
  end
45
38
 
46
39
  #
47
40
  # Set the location for this machine.
48
41
  #
49
- def location=(value)
50
- set_chef_provisioning_attr('location', value)
42
+ def reference=(value)
43
+ attrs.delete('location')
44
+ attrs['reference'] = value
51
45
  end
52
46
 
53
- # URL to the driver. Convenience for location['driver_url']
54
- def driver_url
55
- location ? location['driver_url'] : nil
56
- end
47
+ alias :location :reference
48
+ alias :location= :reference=
57
49
 
58
- #
59
- # Save this node to the server. If you have significant information that
60
- # could be lost, you should do this as quickly as possible. Data will be
61
- # saved automatically for you after allocate_machine and ready_machine.
62
- #
63
- def save(action_handler)
64
- raise "save unimplemented"
50
+ def from_image
51
+ attrs['from_image']
65
52
  end
66
-
67
- protected
68
-
69
- def chef_provisioning_attr(attr)
70
- if node['normal'] && node['normal']['chef_provisioning']
71
- node['normal']['chef_provisioning'][attr]
72
- end
73
- end
74
-
75
- def set_chef_provisioning_attr(attr, value)
76
- node['normal'] ||= {}
77
- node['normal']['chef_provisioning'] ||= {}
78
- node['normal']['chef_provisioning'][attr] = value
53
+ def from_image=(value)
54
+ attrs['from_image'] = value
79
55
  end
80
56
  end
81
57
  end
@@ -0,0 +1,121 @@
1
+ class Chef
2
+ module Provisioning
3
+ #
4
+ # Specification for a managed thing. Remembers where it was stored, and lets
5
+ # you stuff reference data in it.
6
+ #
7
+ class ManagedEntry
8
+ def initialize(managed_entry_store, resource_type, name, data=nil)
9
+ @managed_entry_store = managed_entry_store
10
+ @resource_type = resource_type
11
+ @name = name
12
+ @data = data || {}
13
+ end
14
+
15
+ attr_reader :managed_entry_store
16
+ attr_reader :resource_type
17
+ attr_reader :name
18
+ attr_reader :data
19
+
20
+ def attrs
21
+ data
22
+ end
23
+
24
+ #
25
+ # Globally unique identifier for this machine. Does not depend on the machine's
26
+ # reference or existence.
27
+ #
28
+ def id
29
+ managed_entry_store.identifier(resource_type, name)
30
+ end
31
+
32
+ #
33
+ # Reference to this managed thing. This should be a freeform hash, with enough
34
+ # information for the driver to look it up and create a Machine object to
35
+ # access it.
36
+ #
37
+ # This MUST include a 'driver_url' attribute with the driver's URL in it.
38
+ #
39
+ # chef-provisioning will do its darnedest to not lose this information.
40
+ #
41
+ def reference
42
+ # Backcompat: old data bags didn't have the "reference" field. If we have
43
+ # no reference field in the data, and the data bag is non-empty, return
44
+ # the root of the data bag.
45
+ attrs['reference'] || attrs['location'] || (attrs == {} ? nil : attrs)
46
+ end
47
+
48
+ #
49
+ # Set the reference for this machine.
50
+ #
51
+ def reference=(value)
52
+ self.attrs['reference'] = value
53
+ end
54
+
55
+ # URL to the driver.
56
+ def driver_url
57
+ attrs['driver_url'] || (reference ? reference['driver_url'] : nil)
58
+ end
59
+ def driver_url=(value)
60
+ attrs['driver_url'] = value
61
+ end
62
+
63
+ #
64
+ # Save this node to the server. If you have significant information that
65
+ # could be lost, you should do this as quickly as possible. Data will be
66
+ # saved automatically for you after allocate_machine and ready_machine.
67
+ #
68
+ def save(action_handler)
69
+ managed_entry_store.save_data(resource_type, name, data, action_handler)
70
+ end
71
+
72
+ def delete(action_handler)
73
+ managed_entry_store.delete_data(resource_type, name, action_handler)
74
+ end
75
+
76
+
77
+ #
78
+ # Subclass interface
79
+ #
80
+
81
+ #
82
+ # Get the given data
83
+ #
84
+ # @param resource_type [Symbol] The type of thing to retrieve (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet, ...)
85
+ # @param name [String] The unique identifier of the thing to retrieve
86
+ #
87
+ # @return [Hash,Array] The data, or `nil` if the data does not exist. Will be JSON- and YAML-compatible (Hash, Array, String, Integer, Boolean, Nil)
88
+ #
89
+ def get_data(resource_type, name)
90
+ raise NotImplementedError, :delete_data
91
+ end
92
+
93
+ #
94
+ # Save the given data
95
+ #
96
+ # @param resource_type [Symbol] The type of thing to save (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet ...)
97
+ # @param name [String] The unique identifier of the thing to save
98
+ # @param data [Hash,Array] The data to save. Must be JSON- and YAML-compatible (Hash, Array, String, Integer, Boolean, Nil)
99
+ #
100
+ def save_data(resource_type, name, data, action_handler)
101
+ raise NotImplementedError, :delete_data
102
+ end
103
+
104
+ #
105
+ # Delete the given data
106
+ #
107
+ # @param resource_type [Symbol] The type of thing to delete (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet, ...)
108
+ # @param name [String] The unique identifier of the thing to delete
109
+ #
110
+ # @return [Boolean] Whether anything was deleted or not.
111
+ #
112
+ def delete_data(resource_type, name, action_handler)
113
+ raise NotImplementedError, :delete_data
114
+ end
115
+
116
+ def identifier(resource_type, name)
117
+ raise NotImplementedError, :identifier
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,136 @@
1
+ require 'chef/provisioning/load_balancer_spec'
2
+ require 'chef/provisioning/machine_spec'
3
+ require 'chef/provisioning/machine_image_spec'
4
+ require 'chef/provisioning/managed_entry'
5
+
6
+ class Chef
7
+ module Provisioning
8
+ class ManagedEntryStore
9
+ def initialize(chef_run_data)
10
+ @chef_run_data = chef_run_data
11
+ end
12
+
13
+ #
14
+ # Get the given data
15
+ #
16
+ # @param resource_type [Symbol] The type of thing to retrieve (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet, ...)
17
+ # @param name [String] The unique identifier of the thing to retrieve
18
+ #
19
+ # @return [Hash,Array] The data. Will be JSON- and YAML-compatible (Hash, Array, String, Integer, Boolean, Nil)
20
+ #
21
+ def get_data(resource_type, name)
22
+ raise NotImplementedError, :get_data
23
+ end
24
+
25
+ #
26
+ # Save the given data
27
+ #
28
+ # @param resource_type [Symbol] The type of thing to save (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet ...)
29
+ # @param name [String] The unique identifier of the thing to save
30
+ # @param data [Hash,Array] The data to save. Must be JSON- and YAML-compatible (Hash, Array, String, Integer, Boolean, Nil)
31
+ #
32
+ def save_data(resource_type, name, data, action_handler)
33
+ raise NotImplementedError, :save_data
34
+ end
35
+
36
+ #
37
+ # Delete the given data
38
+ #
39
+ # @param resource_type [Symbol] The type of thing to delete (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet, ...)
40
+ # @param name [String] The unique identifier of the thing to delete
41
+ #
42
+ # @return [Boolean] Whether anything was deleted or not.
43
+ #
44
+ def delete_data(resource_type, name, action_handler)
45
+ raise NotImplementedError, :delete_data
46
+ end
47
+
48
+ #
49
+ # Get a globally unique identifier for this resource.
50
+ #
51
+ # @param resource_type [Symbol] The type of spec to retrieve (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet, ...)
52
+ # @param name [String] The unique identifier of the spec to retrieve
53
+ #
54
+ # @return [String] The identifier.
55
+ #
56
+ # @example ChefManagedEntry does this:
57
+ # chef_managed_entry_store.identifier(:machine, 'mario') # => https://my.chef.server/organizations/org/nodes/mario
58
+ #
59
+ def identifier(resource_type, name)
60
+ raise NotImplementedError, :identifier
61
+ end
62
+
63
+ #
64
+ # Get a spec.
65
+ #
66
+ # @param resource_type [Symbol] The type of spec to retrieve (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet, ...)
67
+ # @param name [String] The unique identifier of the spec to retrieve
68
+ #
69
+ # @return [ManagedEntry] The entry, or `nil` if the data does not exist.
70
+ #
71
+ def get(resource_type, name)
72
+ data = get_data(resource_type, name)
73
+ if data
74
+ new_entry(resource_type, name, data)
75
+ end
76
+ end
77
+
78
+ #
79
+ # Get a spec, or create a new one, depending on whether an entry exists.
80
+ #
81
+ # @param resource_type [Symbol] The type of spec to retrieve (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet, ...)
82
+ # @param name [String] The unique identifier of the spec to retrieve
83
+ #
84
+ # @return [ManagedEntry] The entry.
85
+ #
86
+ def get_or_new(resource_type, name)
87
+ data = get_data(resource_type, name)
88
+ new_entry(resource_type, name, data)
89
+ end
90
+
91
+ #
92
+ # Get a spec, erroring out if the data does not exist.
93
+ #
94
+ # @param resource_type [Symbol] The type of spec to retrieve (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet, ...)
95
+ # @param name [String] The unique identifier of the spec to retrieve
96
+ #
97
+ # @return [ManagedEntry] The entry.
98
+ #
99
+ def get!(resource_type, name)
100
+ result = get(resource_type, name)
101
+ if !result
102
+ raise "#{identifier(resource_type, name)} not found!"
103
+ end
104
+ result
105
+ end
106
+
107
+ #
108
+ # Delete the given spec.
109
+ #
110
+ # @param resource_type [Symbol] The type of spec to delete (:machine, :machine_image, :load_balancer, :aws_vpc, :aws_subnet, ...)
111
+ # @param name [String] The unique identifier of the spec to delete
112
+ #
113
+ # @return [Boolean] Whether anything was deleted or not.
114
+ #
115
+ def delete(resource_type, name, action_handler)
116
+ delete_data(resource_type, name, action_handler)
117
+ end
118
+
119
+ #
120
+ # Create a new managed entry of the given type.
121
+ #
122
+ def new_entry(resource_type, name, data=nil)
123
+ case resource_type
124
+ when :machine
125
+ MachineSpec.new(self, resource_type, name, data)
126
+ when :machine_image
127
+ MachineImageSpec.new(self, resource_type, name, data)
128
+ when :load_balancer
129
+ LoadBalancerSpec.new(self, resource_type, name, data)
130
+ else
131
+ ManagedEntry.new(self, resource_type, name, data)
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end