knife-pinnings 1.3.0 → 1.4.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e2513585158f431721111e6e1f9ac0c81cc04f6f
4
- data.tar.gz: 375f8e8645245063b8292a39f96596eaee35962d
3
+ metadata.gz: 736339371fde27134633d459027749081e8b97a2
4
+ data.tar.gz: 6dbf3a1a701dea77ddbc406342a11a2f11beda01
5
5
  SHA512:
6
- metadata.gz: 1b91f419025fb2deea338b75bd767a7024f9060df45d1b112e6d1104b08334c2ff320e3a299576cdd2de82cb8303a6b2aa8bd23085ff82aef06f1dba6fd6d940
7
- data.tar.gz: 075ce2f502d4f9c76b29e4006be44ca534e6d70f4f6ed1d7964ffabd4de409b9d73fc9c4ec90234a997edb7eb0f2f0b54e3bed3b159834f681fcb394ef75b5b3
6
+ metadata.gz: 3b26b524d34e3795895bc7b1d2d3f2df7a4d5bc1936906b0877650c784b63cfbd5fe810b896bd32294186daff2eeda466c136417f0944fe6dabe306dd29677f0
7
+ data.tar.gz: c0e02d3e7c4e56d1875a00332d668ef87bbd4b7a2714a2e62bc1a0cf4d191616f62fe80652f4fb3db077bbbaf66ce4c3760d609a212c74ccaafc4480e4ea686c
@@ -5,9 +5,16 @@ More information at <http://semver.org/>
5
5
 
6
6
  Given a version xx.yy.zz
7
7
 
8
- * A change in zz is a bug fix
8
+ * A change in xx is a major change which likely breaks stuff that depends on us.
9
9
  * A change in yy is a non-breaking change (usually a new feature)
10
- * A change in zz is a major change which likely breaks stuff that depends on us.
10
+ * A change in zz is a bug fix
11
+
12
+ ## 1.4.0
13
+ * Add a pinnings 'set auto' command that discover policies from a chef environment and solve versions
14
+
15
+ ## 1.3.0
16
+ * Add `knife pinnings local cookbook [name|version]`
17
+ * Clean up some complexity in grid code
11
18
 
12
19
  ## 1.1.2
13
20
  * Use variable column spacing in grid (reduces width of grid)
data/README.md CHANGED
@@ -30,6 +30,15 @@ To take the name and version from the metadata.rb in the current directory use
30
30
 
31
31
  $ knife pinnings set <environment>
32
32
 
33
+ To leverage chef resolver to find out all cookbook versions used by all nodes of a given chef environment and set them back in the environment (typically latest versions will be resolved)
34
+
35
+ $ knife pinnings set auto <environment>
36
+
37
+ To perform the same as above, but specifying some cookbook version constraints as input for chef resolver
38
+
39
+ $ knife pinnings set auto <environment> <cookbook_constraints> (<cookbook_constraints> syntax: apache@0.2.0,log_rotate@1.4.0)
40
+
41
+
33
42
 
34
43
  ### List pinnings
35
44
  In general you can use
@@ -78,6 +87,14 @@ To wipe my skunk app cookbooks from development
78
87
 
79
88
  knife pinnings wipe development '^skunk_app.*'
80
89
 
90
+
91
+ ### Local cookbook metadata
92
+
93
+ To get local cookbook metadata for use in shell scripts
94
+
95
+ knife pinnings local cookbook [name|version]
96
+
97
+
81
98
  ## Contributing
82
99
 
83
100
  1. Fork it ( <https://github.com/trickyearlobe/knife-pinnings/fork> )
@@ -75,6 +75,15 @@ def build_pinnings_table(environments, cookbook_regex)
75
75
  cookbooks_grid
76
76
  end
77
77
 
78
+ def set_environnment_pinnings(environment, pinnings)
79
+
80
+ pinnings.each do |name,pinning|
81
+ environment.cookbook_versions[name] = pinning
82
+ end
83
+ environment.save
84
+
85
+ end
86
+
78
87
  def add_color(row)
79
88
  label, *elements = row
80
89
  label = ui.color(label, :white)
@@ -109,3 +118,66 @@ def display_cookbooks(cookbooks, cookbook_regex)
109
118
  end
110
119
  ui.msg(ui.list(rows, :uneven_columns_across, 2)) if rows.length > 0
111
120
  end
121
+
122
+ def nodes_in(rest, environment)
123
+ rest.get_rest("/environments/#{environment}/nodes").keys
124
+ end
125
+
126
+ def cookbooks_used_by(rest, environment, nodes)
127
+ recipes = []
128
+ roles = []
129
+ nodes.each do |node|
130
+ response = rest.get_rest("/nodes/#{node}").run_list
131
+ _recipes = response.recipe_names
132
+ _roles = response.role_names
133
+ recipes = recipes | (if (_recipes==nil) then [] else _recipes end)
134
+ roles = roles | (if (_roles==nil) then [] else _roles end)
135
+ end
136
+ recipes_from_roles = []
137
+ roles.each do |role|
138
+ run_list = [Chef::RunList::RunListItem.new("role[#{role}]")]
139
+ expansion = Chef::RunList::RunListExpansionFromAPI.new(environment, run_list, rest)
140
+ expansion.expand
141
+ recipes_from_roles = recipes_from_roles | expansion.recipes
142
+ end
143
+ (recipes | recipes_from_roles).map { |r| r.split('@').first.split('::').first }
144
+ end
145
+
146
+ def cookbooks_merged_with_version_constraints(cookbooks, cookbook_version_constraints)
147
+ cookbooks_with_contraints = cookbooks.dup
148
+ cookbook_version_constraints.each do |cookbook_version_constraint|
149
+ if (not cookbook_version_constraint_valid?(cookbook_version_constraint))
150
+ raise "cookbook constraint #{cookbook_version_constraint} is not valid, it should have format like zed@1.2.3"
151
+ else
152
+ cookbook_name = cookbook_version_constraint.split('@')[0]
153
+ if(cookbooks_with_contraints.include?(cookbook_name))
154
+ cookbooks_with_contraints.delete(cookbook_name)
155
+ end
156
+ cookbooks_with_contraints.push(cookbook_version_constraint)
157
+ end
158
+ end
159
+ cookbooks_with_contraints
160
+ end
161
+
162
+ def cookbook_version_constraint_valid?(cookbook_constraint)
163
+ if (not cookbook_constraint.include?('@'))
164
+ ui.fatal("cookbook constraint #{cookbook_constraint} should include @")
165
+ false
166
+ end
167
+ if ( ( cookbook_constraint.split('@')[1] =~ /\A\d+(?:\.\d+)*\z/) != 0 )
168
+ ui.fatal("cookbook constraint #{cookbook_constraint} does not have valid version number")
169
+ false
170
+ end
171
+ true
172
+ end
173
+
174
+ def solve_recipes(rest, environment, cookbooks_with_contraints)
175
+ run_list = Hash.new
176
+ run_list["run_list"] = cookbooks_with_contraints
177
+ response = rest.post_rest("/environments/#{environment}/cookbook_versions",{:run_list => cookbooks_with_contraints})
178
+ solution = Hash.new
179
+ response.sort.each do |name, cb|
180
+ solution[name]=cb.version
181
+ end
182
+ return solution
183
+ end
@@ -0,0 +1,62 @@
1
+ # Copyright 2015 Richard Nixon
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ class Chef
16
+ class Knife
17
+ # This class knife pinnings set auto ['environment'] ['cookbook_regex']
18
+ class PinningsSetAuto < Chef::Knife
19
+ require 'chef/knife/pinnings_mixin'
20
+ banner 'knife pinnings set auto ENVIRONMENT [COOKBOOK_VERSION_CONSTRAINTS]'
21
+
22
+ def run
23
+ case name_args.length
24
+ when 1 # Just environment was specified
25
+ @environment_name = name_args[0]
26
+ when 2 # Environment, and cookbook version constraints specified
27
+ @environment_name = name_args[0]
28
+ @cookbook_version_constraints_string = name_args[1]
29
+ @cookbook_version_constraints = @cookbook_version_constraints_string.split(",")
30
+ else
31
+ ui.fatal('You must specify ENVIRONMENT or ENVIRONMENT COOKBOOK_CONSTRAINTS (constraints example: "foo","bar","zed@0.0.1")')
32
+ exit 255
33
+ end
34
+ @environment = Environment.load(@environment_name)
35
+ nodes = nodes_in(rest, @environment)
36
+ ui.info("#{nodes.length} nodes have been found in environment #{@environment_name}: #{nodes.to_s}")
37
+ cookbooks = cookbooks_used_by(rest, @environment_name, nodes)
38
+ ui.info("#{cookbooks.length} recipes have been found for the nodes: #{cookbooks.to_s}")
39
+ if @cookbook_version_constraints != nil
40
+ cookbooks_with_contraints = cookbooks_merged_with_version_constraints(cookbooks, @cookbook_version_constraints)
41
+ ui.info("the cookbook version constraints are as follow: #{cookbooks_with_contraints.to_s}")
42
+ else
43
+ ui.info("No version constraint have been specified as input")
44
+ cookbooks_with_contraints = cookbooks
45
+ end
46
+ ui.info("will attempt resolving the dependencies with chef resolver...")
47
+ solution_pinnings = solve_recipes(rest, @environment, cookbooks_with_contraints)
48
+ ui.msg('')
49
+ ui.info("chef resolved the cookbook dependencies for all nodes from #{@environment_name} as follow:")
50
+ solution_pinnings.map{|key,val| "#{key} --- #{val}"}.each{|entry| ui.info(entry)}
51
+
52
+ ui.msg('')
53
+ ui.confirm("Do you want to set these cookbook versions on chef environment:#{@environment_name} ")
54
+ ui.msg('')
55
+
56
+ set_environnment_pinnings(@environment, solution_pinnings)
57
+ ui.info("pinnings have been set on #{@environment_name}")
58
+
59
+ end
60
+ end
61
+ end
62
+ end
@@ -15,7 +15,7 @@
15
15
  # rubocop:disable Style/Documentation
16
16
  module Knife
17
17
  module Pinnings
18
- VERSION = '1.3.0'
18
+ VERSION = '1.4.1'
19
19
  MAJOR, MINOR, TINY = VERSION.split('.')
20
20
  end
21
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-pinnings
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Nixon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-12 00:00:00.000000000 Z
11
+ date: 2015-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef
@@ -159,6 +159,7 @@ files:
159
159
  - lib/chef/knife/pinnings_mixin.rb
160
160
  - lib/chef/knife/pinnings_promote.rb
161
161
  - lib/chef/knife/pinnings_set.rb
162
+ - lib/chef/knife/pinnings_set_auto.rb
162
163
  - lib/chef/knife/pinnings_wipe.rb
163
164
  - lib/knife-pinnings/version.rb
164
165
  homepage: https://github.com/trickyearlobe/knife-pinnings