chef-provisioning 0.19 → 0.20

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 (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