Module: Scooter::HttpDispatchers::Classifier
- Included in:
- ConsoleDispatcher
- Defined in:
- lib/scooter/httpdispatchers/classifier.rb,
lib/scooter/httpdispatchers/classifier/v1/v1.rb
Overview
Methods added here are not representative of endpoints, but are more generalized to be helpers to to acquire/transform data, such as getting the uuid of a node group based on the name. Be cautious about using these methods if you are utilizing a dispatcher with credentials; the user is not guaranteed to have privileges for all the methods defined here, or the user may not be signed in. If you have a method defined here that is using the connection object directly, you should probably be using a method defined in the version module instead.
Defined Under Namespace
Modules: V1
Constant Summary collapse
- Rootuuid =
'00000000-0000-4000-8000-000000000000'
Instance Method Summary collapse
-
#classes_match?(other_classes, self_classes = nil) ⇒ Boolean
Check to see if all classes match between two query responses.
-
#classifier_database_matches_self?(replica_host) ⇒ Boolean
Used to compare replica classifier to master.
-
#create_new_node_group_model(options = {}) ⇒ Object
(also: #generate_node_group)
This takes an optional hash of node group parameters, and auto-fills any required keys for node group generation.
-
#delete_all_node_groups ⇒ Object
This method deletes all the descendents of the Rootuuid; the root group can never be deleted.
-
#delete_node_group_descendents(node_group_model) ⇒ Object
This will delete anything that inherits from the node group specified, but not the actual node group itself.
-
#delete_tree_recursion(tree, node_group_id) ⇒ Object
The tree parameter required here is generated from the method
get_node_group_trees_with_direct_descendents
. -
#environments_match?(other_environments, self_environments = nil) ⇒ Boolean
Check to see if all environments match between two query responses.
-
#find_or_create_node_group_model(options = {}) ⇒ Object
This takes an optional hash of node group parameters.
-
#get_node_group_by_name(name, environment = 'production') ⇒ Object
This will return a node group hash given the name of the node group.
-
#get_node_group_id_by_name(name, environment = 'production') ⇒ Object
This will return the node group id given the name of the node group.
-
#get_node_group_trees_of_direct_descendents ⇒ Object
This returns a tree-like hash of all node groups in the classifier; each key is a uuid, each value is an array of direct children.
-
#groups_match?(other_groups, self_groups = nil) ⇒ Boolean
Check to see if all groups match between two query responses.
-
#import_baseline_hierarchy ⇒ Object
This method imports a bare root group into the NC, cleaning out and deleting any node groups that might have been available.
-
#nodes_match?(other_nodes, self_nodes = nil) ⇒ Boolean
Check to see if all nodes match between two query responses.
-
#refresh_node_group_model(node_group_model) ⇒ Object
If for some reason your node group model is out of sync with the server’s state for that node group, you can use this method to just update your model with the server state.
-
#replace_node_group_with_update_hash(node_group_model, update_hash) ⇒ Object
This uses a PUTs instead of a POST to update a node group; when using PUTs, it will delete and replace the entire node group instead of just updating the keys provided.
- #set_classifier_path(connection = self.connection) ⇒ Object
-
#update_node_group_with_node_group_model(node_group_model, update_hash) ⇒ Object
This uses the POST method to update a node group; when using POST, it will only send and update the specified keys.
Methods included from V1
#create_node_group, #delete_node_group, #get_list_of_classes, #get_list_of_environments, #get_list_of_node_groups, #get_list_of_nodes, #get_node_group, #import_hierarchy, #pin_nodes, #replace_node_group, #unpin_nodes, #update_classes, #update_node_group
Instance Method Details
#classes_match?(other_classes, self_classes = nil) ⇒ Boolean
Check to see if all classes match between two query responses
355 356 357 358 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 355 def classes_match?(other_classes, self_classes=nil) self_classes = get_list_of_classes if self_classes.nil? return other_classes == self_classes end |
#classifier_database_matches_self?(replica_host) ⇒ Boolean
Used to compare replica classifier to master. Raises exception if it does not match.
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 309 def classifier_database_matches_self?(replica_host) original_host_name = host.host_hash[:vmhostname] begin host.host_hash[:vmhostname] = replica_host.hostname other_nodes = get_list_of_nodes other_classes = get_list_of_classes other_environments = get_list_of_environments other_groups = get_list_of_node_groups ensure host.host_hash[:vmhostname] = original_host_name end self_nodes = get_list_of_nodes self_classes = get_list_of_classes self_environments = get_list_of_environments self_groups = get_list_of_node_groups nodes_match = nodes_match?(other_nodes, self_nodes) classes_match = classes_match?(other_classes, self_classes) environments_match = environments_match?(other_environments, self_environments) groups_match = groups_match?(other_groups, self_groups) errors = '' errors << "Nodes do not match\r\n" unless nodes_match errors << "Classes do not match\r\n" unless classes_match errors << "Environments do not match\r\n" unless environments_match errors << "Groups do not match\r\n" unless groups_match host.logger.warn(errors.chomp) unless errors.empty? errors.empty? end |
#create_new_node_group_model(options = {}) ⇒ Object Also known as: generate_node_group
This takes an optional hash of node group parameters, and auto-fills any required keys for node group generation. It returns the response body from the server.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 87 def create_new_node_group_model(={}) # name, classes, parent are the only required keys name = ['name'] || RandomString.generate classes = ['classes'] || {} parent = ['parent'] || Rootuuid rule = ['rule'] id = ['id'] environment = ['environment'] variables = ['variables'] description = ['description'] environment_trumps = ['environment_trumps'] hash = { "name" => name, "parent" => parent, "classes" => classes } if environment_trumps hash['environment_trumps'] = environment_trumps end if rule hash['rule'] = rule end if environment hash['environment'] = environment end if variables hash['variables'] = variables end if description hash['description'] = description end if id hash['id'] = id end create_node_group(hash).env.body end |
#delete_all_node_groups ⇒ Object
This method deletes all the descendents of the Rootuuid; the root group can never be deleted. If you are looking to clean out a system entirely, consider using import_baseline_hierarchy
instead, as this method doesn’t clean out any classes or other settings the root group might have.
80 81 82 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 80 def delete_all_node_groups delete_node_group_descendents(get_node_group(Rootuuid)) end |
#delete_node_group_descendents(node_group_model) ⇒ Object
This will delete anything that inherits from the node group specified, but not the actual node group itself.
155 156 157 158 159 160 161 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 155 def delete_node_group_descendents(node_group_model) id = node_group_model['id'] tree = get_node_group_trees_of_direct_descendents tree[id].each do |childid| delete_tree_recursion(tree, childid) end end |
#delete_tree_recursion(tree, node_group_id) ⇒ Object
The tree parameter required here is generated from the method get_node_group_trees_with_direct_descendents
. This method will also delete the node_group_id as well.
192 193 194 195 196 197 198 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 192 def delete_tree_recursion(tree, node_group_id) tree[node_group_id].each do |childid| delete_tree_recursion(tree, childid) end #protect against trying to delete the Rootuuid delete_node_group(node_group_id) if node_group_id != Rootuuid end |
#environments_match?(other_environments, self_environments = nil) ⇒ Boolean
Check to see if all environments match between two query responses
373 374 375 376 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 373 def environments_match?(other_environments, self_environments=nil) self_environments = get_list_of_environments if self_environments.nil? return other_environments == self_environments end |
#find_or_create_node_group_model(options = {}) ⇒ Object
This takes an optional hash of node group parameters. If a “name” option is provided it will attempt to find an existing node group with that name in the environment specified in the “environment” option (default: “production”).
If an existing node group is found, it will be updated according to the provided options (via ‘#replace_node_group_with_update_hash`).
If no existing node group is found, the options hash will be used to create a new node group (via ‘#create_new_node_group_model`).
137 138 139 140 141 142 143 144 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 137 def find_or_create_node_group_model(={}) ["environment"] ||= "production" if ["name"] && existing = get_node_group_by_name(["name"], ["environment"]) replace_node_group_with_update_hash(existing, ) else create_new_node_group_model() end end |
#get_node_group_by_name(name, environment = 'production') ⇒ Object
This will return a node group hash given the name of the node group. It defaults to production for the environment, since node names can be the same for different environments.
166 167 168 169 170 171 172 173 174 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 166 def get_node_group_by_name(name, environment='production') nodes = get_list_of_node_groups nodes.each do |node| if node['name'] == name && node['environment'] == environment return node end end nil # return nil if no matching name found end |
#get_node_group_id_by_name(name, environment = 'production') ⇒ Object
This will return the node group id given the name of the node group. It defaults to production for the environment, since node names can be the same for different environments.
179 180 181 182 183 184 185 186 187 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 179 def get_node_group_id_by_name(name, environment='production') nodes = get_list_of_node_groups nodes.each do |node| if node['name'] == name && node['environment'] == environment return node['id'] end end nil # return nil if no matching name found end |
#get_node_group_trees_of_direct_descendents ⇒ Object
This returns a tree-like hash of all node groups in the classifier; each key is a uuid, each value is an array of direct children. If no direct children are found, the value is an empty array. This representation is useful for iterating over specific children of known node groups, and is using primarily in delete_node_group_descendents
and delete_tree_recursion
.
Example return hash for default PE Installation
{ "00000000-0000-4000-8000-000000000000" => # root group with one child
["6d37be98-42ee-400d-a66e-ebced989546c"],
"6d37be98-42ee-400d-a66e-ebced989546c" => # node group with 5 kids
["42e385ca-8fb2-442d-a0af-3b14c86d321b",
"32e6a36d-59ad-44ea-8708-feb910907058",
"44ebbb50-501c-45f1-8c92-95d5b0313d24",
"58448b7d-3175-4695-ac32-31cf4ee25754",
"00350026-bfb6-4ce7-bd06-1a1cfea445f9",
"b6400234-2a61-4417-b85e-c2dcc123686b"],
"42e385ca-8fb2-442d-a0af-3b14c86d321b" => [], # childless node group
"32e6a36d-59ad-44ea-8708-feb910907058" => [],
"44ebbb50-501c-45f1-8c92-95d5b0313d24" => [],
"58448b7d-3175-4695-ac32-31cf4ee25754" => [],
"00350026-bfb6-4ce7-bd06-1a1cfea445f9" => [],
"b6400234-2a61-4417-b85e-c2dcc123686b" => [] }
47 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 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 47 def get_node_group_trees_of_direct_descendents node_groups = get_list_of_node_groups groups = node_groups.map { |each| [each['id'], each['parent']] } # Constants for the array of tuples just created. id = 0 parent = 1 # Create root node and insert it into the tree hash. rootindex = groups.find_index { |e| e[id] == e[parent] } rootid = (groups.delete_at(rootindex))[id] tree = Object::Hash.new tree[rootid] = Object::Array.new # Construct the rest of the tree as a hash of # id => [ child1, child2,...] nodes. groups.each do |g| tree[g[id]] = Object::Array.new if tree.has_key?(g[parent]) then tree[g[parent]] << g[id] else tree[g[parent]] = Object::Array.new tree[g[parent]] << g[id] end end tree end |
#groups_match?(other_groups, self_groups = nil) ⇒ Boolean
Check to see if all groups match between two query responses
364 365 366 367 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 364 def groups_match?(other_groups, self_groups=nil) self_groups = get_list_of_node_groups if self_groups.nil? return other_groups == self_groups end |
#import_baseline_hierarchy ⇒ Object
This method imports a bare root group into the NC, cleaning out and deleting any node groups that might have been available. Consider using this or delete_all_node_groups
at the beginning of your test, depending on requirements of the test.
204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 204 def import_baseline_hierarchy hierarchy = [{ "environment_trumps" => false, "parent" => Rootuuid, "name" => "default", "rule" => ["and", ["~", "name", ".*"]], "variables" => {}, "id" => Rootuuid, "environment" => "production", "classes" => {} }] import_hierarchy(hierarchy) end |
#nodes_match?(other_nodes, self_nodes = nil) ⇒ Boolean
Check to see if all nodes match between two query responses
346 347 348 349 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 346 def nodes_match?(other_nodes, self_nodes=nil) self_nodes = get_list_of_nodes if self_nodes.nil? return other_nodes == self_nodes end |
#refresh_node_group_model(node_group_model) ⇒ Object
If for some reason your node group model is out of sync with the server’s state for that node group, you can use this method to just update your model with the server state.
149 150 151 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 149 def refresh_node_group_model(node_group_model) get_node_group(node_group_model['id']) end |
#replace_node_group_with_update_hash(node_group_model, update_hash) ⇒ Object
This uses a PUTs instead of a POST to update a node group; when using PUTs, it will delete and replace the entire node group instead of just updating the keys provided.
250 251 252 253 254 255 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 250 def replace_node_group_with_update_hash(node_group_model, update_hash) merged_model = node_group_model.merge(update_hash) replace_node_group(merged_model['id'], merged_model) # no verification of the response for now, will need to write some code # that verifies this and takes care of array ordering end |
#set_classifier_path(connection = self.connection) ⇒ Object
20 21 22 23 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 20 def set_classifier_path(connection=self.connection) set_url_prefix connection.url_prefix.path = '/classifier-api' end |
#update_node_group_with_node_group_model(node_group_model, update_hash) ⇒ Object
This uses the POST method to update a node group; when using POST, it will only send and update the specified keys.
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/scooter/httpdispatchers/classifier.rb', line 259 def update_node_group_with_node_group_model(node_group_model, update_hash) id = node_group_model['id'] response = update_node_group(id, update_hash) deep_merge(node_group_model, update_hash) node_group_model = remove_nil_values(node_group_model) # check to see if the update hash had any class changes that require # transforms to the groups['deleted'] object if node_group_model['deleted'] && node_group_model['classes'] != {} && update_hash['classes'] update_hash['classes'].each do |classname, parameters| if node_group_model['deleted'][classname] == nil next end parameters.each do |parameter, value| if value == nil node_group_model['deleted'][classname].delete(parameter) else node_group_model['deleted'][classname][parameter]['value'] = value end end end end # check to see if we need to delete any classes from the model's # node_group_model{'deleted'] key if node_group_model['deleted'] node_group_model['deleted'].each do |classname, parameters| if node_group_model['classes'][classname] == nil || node_group_model['deleted'][classname].keys == ['puppetlabs.classifier/deleted'] node_group_model['deleted'].delete(classname) end end node_group_model.delete('deleted') if node_group_model['deleted'] == {} end node_group_model.delete('serial_number') node_group_model.delete('last_edited') response.env.body.delete('serial_number') response.env.body.delete('last_edited') if node_group_model != response.env.body raise "node_group_model did not match the server response:\n#{node_group_model}\n#{response.env.body}" end # If we got this far, return the "model" hash. node_group_model end |