Class: MCollective::Util::Playbook::Uses
- Inherits:
-
Object
- Object
- MCollective::Util::Playbook::Uses
- Defined in:
- lib/mcollective/util/playbook/uses.rb
Instance Method Summary collapse
- #[](agent) ⇒ Object
-
#agent_ddl(agent) ⇒ DDL::AgentDDL
Returns the DDL for a specific agent.
-
#agent_inventory(nodes) ⇒ Boolean, ...
Retrieves the agent inventory for a set of nodes.
-
#ddl_version(agent) ⇒ Object
Fetches the DDL version for an agent.
- #from_hash(data) ⇒ Object
-
#initialize(playbook) ⇒ Uses
constructor
A new instance of Uses.
- #keys ⇒ Object
-
#prepare ⇒ Object
Checks that all the declared agent DDLs exist.
-
#valid_version?(have, want) ⇒ Boolean
Determines if a semver version is within a stated range.
-
#validate_agents(agents) ⇒ Object
Validates agent versions on nodes.
Constructor Details
#initialize(playbook) ⇒ Uses
Returns a new instance of Uses.
5 6 7 8 |
# File 'lib/mcollective/util/playbook/uses.rb', line 5 def initialize(playbook) @playbook = playbook @uses = {} end |
Instance Method Details
#[](agent) ⇒ Object
10 11 12 |
# File 'lib/mcollective/util/playbook/uses.rb', line 10 def [](agent) @uses[agent] end |
#agent_ddl(agent) ⇒ DDL::AgentDDL
Returns the DDL for a specific agent
154 155 156 |
# File 'lib/mcollective/util/playbook/uses.rb', line 154 def agent_ddl(agent) DDL::AgentDDL.new(agent) end |
#agent_inventory(nodes) ⇒ Boolean, ...
Retrieves the agent inventory for a set of nodes
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/mcollective/util/playbook/uses.rb', line 22 def agent_inventory(nodes) rpc = Tasks::McollectiveTask.new(@playbook) rpc.from_hash( "nodes" => nodes, "action" => "rpcutil.agent_inventory", "silent" => true ) success, msg, inventory = rpc.run # rpcutil#agent_inventory is a hash in a hash not managed by the DDL # this is not handled by the JSON encoding magic that does DDL based # symbol and string conversion so we normalise the data always to symbol # based structures inventory.each do |node| node["data"][:agents].each do |agent| agent.keys.each do |key| # rubocop:disable Style/HashEachMethods agent[key.intern] = agent.delete(key) if key.is_a?(String) end end end [success, msg, inventory] end |
#ddl_version(agent) ⇒ Object
Fetches the DDL version for an agent
If the agent DDL has versions like 1.0 it will be turned into 1.0.0 as old mco stuff didnt do semver
144 145 146 147 |
# File 'lib/mcollective/util/playbook/uses.rb', line 144 def ddl_version(agent) ddl = agent_ddl(agent) ddl.[:version] end |
#from_hash(data) ⇒ Object
158 159 160 161 162 163 164 165 |
# File 'lib/mcollective/util/playbook/uses.rb', line 158 def from_hash(data) data.each do |agent, version| Log.debug("Loading usage of %s version %s" % [agent, version]) @uses[agent] = version end self end |
#keys ⇒ Object
14 15 16 |
# File 'lib/mcollective/util/playbook/uses.rb', line 14 def keys @uses.keys end |
#prepare ⇒ Object
Checks that all the declared agent DDLs exist
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/mcollective/util/playbook/uses.rb', line 117 def prepare invalid = @uses.map do |agent, want| begin have = ddl_version(agent) if valid_version?(have, want) Log.debug("Agent %s DDL version %s matches desired %s" % [agent, have, want]) nil else Log.warn("Agent %s DDL version %s does not match desired %s" % [agent, have, want]) agent end rescue Log.warn("Could not process DDL for agent %s: %s: %s" % [agent, $!.class, $!.to_s]) agent end end.compact raise("DDLs for agent(s) %s did not match desired versions" % invalid.join(", ")) unless invalid.empty? end |
#valid_version?(have, want) ⇒ Boolean
mcollective never suggested semver, so versions like “1.1” becomes “1.1.0” for the compare
Determines if a semver version is within a stated range
104 105 106 107 108 109 110 111 112 |
# File 'lib/mcollective/util/playbook/uses.rb', line 104 def valid_version?(have, want) have = "%s.0" % have if have.split(".").size == 2 require "semantic_puppet" unless defined?(SemanticPuppet) semver_have = SemanticPuppet::Version.parse(have) semver_want = SemanticPuppet::VersionRange.parse(want) semver_want.include?(semver_have) end |
#validate_agents(agents) ⇒ Object
Validates agent versions on nodes
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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/mcollective/util/playbook/uses.rb', line 52 def validate_agents(agents) nodes = agents.map {|_, agent_nodes| agent_nodes}.flatten.uniq Log.info("Validating agent inventory on %d nodes" % nodes.size) validation_fail = false success, msg, inventory = agent_inventory(nodes) raise("Could not determine agent inventory: %s" % msg) unless success agents.each do |agent, agent_nodes| unless @uses.include?(agent) Log.warn("Agent %s is mentioned in node sets but not declared in the uses list" % agent) validation_fail = true next end agent_nodes.each do |node| unless node_inventory = inventory.find {|i| i["sender"] == node} Log.warn("Did not receive an inventory for node %s" % node) validation_fail = true next end unless = node_inventory["data"][:agents].find {|i| i[:agent] == agent} Log.warn("Node %s does not have the agent %s" % [node, agent]) validation_fail = true next end if valid_version?([:version], @uses[agent]) Log.debug("Agent %s on %s version %s matches desired version %s" % [agent, node, [:version], @uses[agent]]) else Log.warn("Agent %s on %s version %s does not match desired version %s" % [agent, node, [:version], @uses[agent]]) validation_fail = true end end end raise("Network agents did not match specified SemVer specifications in the playbook") if validation_fail Log.info("Agent inventory on %d nodes validated" % nodes.size) end |