Top Level Namespace

Defined Under Namespace

Modules: Knife Classes: Chef

Instance Method Summary collapse

Instance Method Details

#add_color(row) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/chef/knife/pinnings_mixin.rb', line 85

def add_color(row)
  label, *elements = row
  label = ui.color(label, :white)

  element_color = elements_identical?(elements) ? :green : :red

  row = [label]
  elements.each do |element|
    row << ui.color(element, element_color)
  end
  row
end

#build_pinnings_table(environments, cookbook_regex) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/chef/knife/pinnings_mixin.rb', line 48

def build_pinnings_table(environments, cookbook_regex)
  cookbooks = {}

  # Get the cookbooks into a sparse hash of hashes
  environments.each do |environment|
    environment.cookbook_versions.each do |name, version|
      if name =~ /#{cookbook_regex}/
        cookbooks[name] ||= {}
        cookbooks[name][environment.name] = version_strip(version)
      end
    end
  end

  # Make a grid header
  cookbooks_grid = ['']
  environments.each do |environment|
    cookbooks_grid << environment.name
  end

  cookbooks.each do |cookbook_name, versions|
    row = [cookbook_name]
    environments.each do |environment|
      row << (versions[environment.name] || '---')
    end
    row = add_color(row)
    cookbooks_grid += row
  end
  cookbooks_grid
end

#cookbook_version_constraint_valid?(cookbook_constraint) ⇒ Boolean

Returns:

  • (Boolean)


163
164
165
166
167
168
169
170
171
172
173
# File 'lib/chef/knife/pinnings_mixin.rb', line 163

def cookbook_version_constraint_valid?(cookbook_constraint)
  if (not cookbook_constraint.include?('@'))
    ui.fatal("cookbook constraint #{cookbook_constraint} should include @")
    false
  end
  if ( ( cookbook_constraint.split('@')[1] =~ /\A\d+(?:\.\d+)*\z/) != 0 )
    ui.fatal("cookbook constraint #{cookbook_constraint} does not have valid version number")
    false
  end
  true
end

#cookbooks_merged_with_version_constraints(cookbooks, cookbook_version_constraints) ⇒ Object



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/chef/knife/pinnings_mixin.rb', line 147

def cookbooks_merged_with_version_constraints(cookbooks, cookbook_version_constraints)
  cookbooks_with_contraints = cookbooks.dup
  cookbook_version_constraints.each do |cookbook_version_constraint|
    if (not cookbook_version_constraint_valid?(cookbook_version_constraint))
      raise "cookbook constraint #{cookbook_version_constraint} is not valid, it should have format like [email protected]"
    else
      cookbook_name = cookbook_version_constraint.split('@')[0]
      if(cookbooks_with_contraints.include?(cookbook_name))
        cookbooks_with_contraints.delete(cookbook_name)
      end
      cookbooks_with_contraints.push(cookbook_version_constraint)
    end
  end
  cookbooks_with_contraints
end

#cookbooks_used_by(rest, environment) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/chef/knife/pinnings_mixin.rb', line 124

def cookbooks_used_by(rest, environment)
  recipes = []
  roles = []
  nodes = nodes_in(rest, environment)
  nodes.each do |node|
    response=Chef::RunList.new(rest.get_rest("/nodes/#{node}")['run_list'].join(','))
    _recipes = response.recipe_names
    _roles = response.role_names
    recipes = recipes | (if (_recipes==nil) then [] else _recipes end)
    roles = roles | (if (_roles==nil) then [] else _roles end)
  end
  recipes_from_roles = []
  roles.each do |role|
    run_list = [Chef::RunList::RunListItem.new("role[#{role}]")]
    expansion = Chef::RunList::RunListExpansionFromAPI.new(environment, run_list, rest)
    expansion.expand
    recipes_from_roles = recipes_from_roles | expansion.recipes
  end
  recipes.delete ""
  recipes_from_roles.delete ""
  (recipes | recipes_from_roles).map { |r| r.split('@').first.split('::').first }
end

#display_cookbooks(cookbooks, cookbook_regex) ⇒ Object



112
113
114
115
116
117
118
# File 'lib/chef/knife/pinnings_mixin.rb', line 112

def display_cookbooks(cookbooks, cookbook_regex)
  rows = []
  filter_cookbooks(cookbooks, cookbook_regex).each do |name, version|
    rows << "  #{name}" << version_strip(version)
  end
  ui.msg(ui.list(rows, :uneven_columns_across, 2)) if rows.length > 0
end

#display_environments(environments, cookbook_regex) ⇒ Object



105
106
107
108
109
110
# File 'lib/chef/knife/pinnings_mixin.rb', line 105

def display_environments(environments, cookbook_regex)
  environments.each do |environment|
    ui.msg(ui.color(environment.name, :yellow))
    display_cookbooks(environment.cookbook_versions, cookbook_regex)
  end
end

#display_pinnings_table(environments, cookbook_regex) ⇒ Object

This method generates a color coded table of cookbook versions across environments



38
39
40
41
42
43
44
45
46
# File 'lib/chef/knife/pinnings_mixin.rb', line 38

def display_pinnings_table(environments, cookbook_regex)
  ui.msg(
    ui.list(
      build_pinnings_table(environments, cookbook_regex),
      :uneven_columns_across,
      environments.length + 1
    )
  )
end

#elements_identical?(elements) ⇒ Boolean

Returns:

  • (Boolean)


98
99
100
101
102
103
# File 'lib/chef/knife/pinnings_mixin.rb', line 98

def elements_identical?(elements)
  elements.each do |element|
    return false unless element == elements.first
  end
  true
end

#filter_cookbooks(cookbooks, cookbook_regex) ⇒ Object



29
30
31
32
33
34
35
# File 'lib/chef/knife/pinnings_mixin.rb', line 29

def filter_cookbooks(cookbooks, cookbook_regex)
  filtered_cookbooks = []
  cookbooks.each do |name, version|
    filtered_cookbooks << [name, version] if name =~ /#{cookbook_regex}/
  end
  filtered_cookbooks
end

#filter_environments(environments, environment_regex) ⇒ Object

This method takes an array of environments and filters them using a REGEX



21
22
23
24
25
26
27
# File 'lib/chef/knife/pinnings_mixin.rb', line 21

def filter_environments(environments, environment_regex)
  filtered_environments = []
  environments.each do |name, environment|
    filtered_environments << environment  if name =~ /#{environment_regex}/
  end
  filtered_environments
end

#nodes_in(rest, environment) ⇒ Object



120
121
122
# File 'lib/chef/knife/pinnings_mixin.rb', line 120

def nodes_in(rest, environment)
  rest.get_rest("/environments/#{environment}/nodes").keys
end

#set_environnment_pinnings(environment, pinnings) ⇒ Object



78
79
80
81
82
83
# File 'lib/chef/knife/pinnings_mixin.rb', line 78

def set_environnment_pinnings(environment, pinnings)
  pinnings.each do |name,pinning|
    environment.cookbook_versions[name] = pinning
  end
  environment.save
end

#solve_recipes(rest, environment, cookbooks_with_contraints) ⇒ Object



175
176
177
178
179
180
181
182
183
184
# File 'lib/chef/knife/pinnings_mixin.rb', line 175

def solve_recipes(rest, environment, cookbooks_with_contraints)
  run_list = Hash.new
  run_list["run_list"] = cookbooks_with_contraints
  response = rest.post_rest("/environments/#{environment}/cookbook_versions",{:run_list => cookbooks_with_contraints})
  solution = Hash.new
  response.sort.each do |name, cb|
    solution[name]=cb['version']
  end
  return solution
end

#version_strip(version_string) ⇒ Object

This method strips the = off Chef “= xxx.yyy.zzz” versions numbers



16
17
18
# File 'lib/chef/knife/pinnings_mixin.rb', line 16

def version_strip(version_string)
  version_string.match(/()[0-9]*\.[0-9]*\.[0-9]*/).to_s
end