Entries filed under: MCollective

Back to Index

Open Source Twitter Chat on May 28th: #Puppetize

Posted on
By
michelle
in
Blog, Community, DevOps, General News, MCollective, Open Source
Responses
4 Comments »

We’ve had a lot of open source goodness this month, and we want to talk about it and get your feedback. We’re hosting an hour-long Twitter chat on May 28 at 11 am PDT to answer your questions and converse about new releases like PuppetDB, MCollective 2.0, Puppet 3.0 (currently in RC), and more.

We’ll have Michael Stahnke, our community manager; Deepak Giridharagopal, major developer of PuppetDB; R.I. Pienaar, author of MCollective; and Nan Liu, integration specialist, ready to respond and converse on Twitter.

Just tag your tweets and questions with #puppetize to join the conversation, and we’ll tag our responses. If you want to follow what’s going on, just track #puppetize for the full stream. To get an idea of what this is like, check out a snippet of the last Twitter chat we had:

We look forward to talking with you on 2012-05-28 18:00 UTC!

Learn More:

Announcing The Marionette Collective 2.0

Posted on
By
R.I. Pienaar
in
Blog, Community, General News, MCollective, product release
Responses
1 Comment »

I am proud to announce the release of the next major production version of The Marionette Collective (MCollective). This release brings together almost a year’s worth of work and introduces great improvements in security, stability, platform support and new features in the core messaging layer.

The major areas of advance are below:

  • Complete messaging protocol rewrite to enable direct style connectivity that would allow programs to bypass normal discovery instead using their own data sources
  • An additional more robust messaging paradigm supporting a more assured addressing and delivery scheme
  • Batched mode allowing users to address machines in small groups thus avoiding thundering herd and enabling more granular changes
  • A more complete language for expressing discovery that includes and/or/not style queries across the infrastructure
  • Improved Stomp connection security using normal industry standard Certificate Authority validated TLS
  • New connector that uses ActiveMQ-specific features for better performance and scalability
  • Security of the SSL and AES security plugins have been improved for tamper protection by middle men
  • A message validity period has been introduced to lower the window of message replay attacks
  • Better error handling and better logging for Stomp connections
  • JSON output from the ‘rpc’ application
  • Ability to pipe RPC requests into each other creating a chain of related RPC calls
  • Better validations, better error handling and better documentation creation from the DDL
  • Performance improvements in the CLI, more consistently formatted output of received data
  • A Ruby GEM of the client is now made available on rubygems.org
  • The rc script for Debian based systems have been improved to prevent duplicate daemons from running
  • Built in packager for plugins into native OS packages—RedHat and Debian supported
  • MS Windows Support

The full release notes for this release expands on key areas of the above list and you can download this release from our download area, Yum repository or our Apt repository.

R.I. Pienaar Joins Puppet Labs

Posted on
By
Jason
in
Blog, Company, General News, MCollective
Responses
4 Comments »

I am very pleased to announce that R.I. Pienaar, founder and lead developer of the widely used Marionette Collective (MCollective) orchestration tools, has joined Puppet Labs as a Software Architect. R.I.’s message-based orchestration tools have become some of the most widely used tools in systems management, and have literally changed the way that people handle ad-hoc command and control, orchestration, and parallel job management. Having R.I. join the Puppet Labs team is a significant milestone for us, as R.I. will help shape product efforts in MCollective, Puppet, and Puppet Enterprise.

Puppet Labs acquired MCollective from R.I. in late 2010. Since then, MCollective has become a critical piece of the Puppet infrastructure with direct integration in Puppet Enterprise for Live Management, as well as standard orchestration functionality. R.I.’s efforts in this regard have had significant impact on product for the company including Puppet Enterprise 2.0.

R.I. will continue to work on MCollective (since MCollective is now directly integrated into our products), but will also work on some of our new projects to be announced in the future. We are very glad to have R.I.’s considerable creativity and industry experience on the team helping with new products that will give sysadmins new tools and delight Puppet users.

In R.I.’s own words:

I’m really excited to finally be part of the Puppet Labs team. I’ve been part time member for over a year and it’s great to finally be a full time team member. I look forward to the opportunities this new venture brings in helping me further the DevOps eco-system.

Live Management Part 2: Controlling Puppet and Invoking Agents

Posted on
By
Max Martin
in
Blog, How to, MCollective, Tips
Responses
3 Comments »

This post is the second in a series on Live Management, new in Puppet Enterprise 2.0, a capability that lets you visually discover, clone, and manage resources across your entire deployment, all through the graphical interface (GUI). In the first post in this series we covered how to make quick changes across your infrastructure by browsing and cloning resources.

Once you have used the browsing and cloning capabilities to establish a desired configuration, the next step is to Puppetize your infrastructure by building a set of manifests. This process is covered in our Learning Puppet documentation.

After you are working with a fully Puppetized infrastructure, there are several other awesome capabilities available in Live Management that you will be able to take advantage of. These advanced tools are available under the links next to ‘Manage Resources’ at the top of the page: Control Puppet and Advanced Tasks.

Under Control Puppet, you can control the behavior of Puppet on clusters of nodes in your infrastructure. Under Advanced Tasks there are tools available to allow you to directly interact with MCollective, which we’ve incorporated into Puppet Enterprise to support Live Management.

Some background on MCollective before we dive in:
MCollective, also known as Marionette Collective, is a framework on which to build server orchestration or parallel job execution systems. Puppet Labs acquired this open source project in the Fall of 2010 from R.I. Pienaar (@ripienaar) who is now a part of our development team. With this release of PE 2.0 we’ve made it easy to use the greatest capabilities of MCollective through our GUI. It’s easy to extend the capabilities of MCollective yourself, either by installing agents written by members of the Puppet community, or by writing your own. These new agents will automatically have a GUI generated for them within Live Management. This process of extending MCollective and Live Management will be covered in the next post in this series.

Now, back to Live Management.

Clicking the ‘Control Puppet’ link takes you to a page where you can control various aspects of Puppet on your nodes.

Similar to the resource browsing and cloning functionality explored in Part 1 of
the series, you can select various subsets of your nodes in the left pane, using hostname searching or by querying the values of various facts. The commands you can perform on these nodes from the Control Puppet tab include:

  • disable: This disables the daemonized Puppet agent on the selected nodes, so that no Puppet runs will occur until it has been re-enabled. This can be useful for periods where you want to test at-will changes (possibly made through the resource browsing and cloning functionality of Live Management) so that they will not be overwritten by Puppet.
  • enable: The opposite of disable, this will re-enable the Puppet agent daemon on the selected nodes.
  • last_run_summary: This command provides you with a summary of the most recent run of the Puppet agent on the selected nodes.
  • runonce: Kicks off a puppet agent run on the selected nodes, regardless of whether one is scheduled (or whether the daemonized Puppet agent is even enabled). This can be useful to test recent changes to your Puppet manifests in a single run, without actually enabling the daemonized agent.
  • status: Fetches the status of the Puppet daemon from the selected nodes—whether or not it’s enabled, if it’s currently in the middle of a run, and when Puppet was last run.

The Control Puppet tab operates by executing various commands over the MCollective messaging framework. The ‘Advanced Tasks’ link gives you direct control over MCollective agents, simple programs that contain actions to be executed on your nodes when they receive certain messages from MCollective. Clicking ‘Advanced Tasks’ will show you a list of all of the MCollective agents you currently have installed on your nodes.

In this example, we show the default agents that are accessible from Puppet Enterprise 2.0. Clicking the name of any given agent will show you its actions, which you can then execute on the currently selected set of nodes. Actions can be run by clicking their name, then clicking the ‘Run’ button that appears. If any input is required for the action, an input field will appear. Some of the agents that ship with Puppet Enterprise and can be controlled through the ‘Advanced Tasks’ tab include:

package: An agent for managing packages. This has various actions to check for updates, update packages, and more.

puppetral: Allows you to search for information about resources from Puppet’s resource abstraction layer. This is the agent that resource browsing and cloning uses under the hood.

rpcutil: A utility agent used by MCollective to collect various information about nodes. This includes information about the agents they have, their facts, and more.

service: An agent for controlling various services on your system (such as httpd, or Puppet and MCollective themselves). You can also use this agent to check the status of various services.

Any of these actions can be run on any cluster in your infrastructure quickly and easily through the Advanced Tasks pane, making this an exceptionally useful and powerful tool in your systems management. In the next post in this series, I’ll be covering how to add more MCollective agents to your infrastructure and get them to show up in Live Management.

Additional Resource:

Santa Clara Schedule: “Asynchronous Real-time Monitoring with MCollective” at Velocity; Puppet Labs Happy Hour

Posted on
By
michelle
in
Blog, Community, General News, MCollective
Responses
0 Comments

Going to Velocity? Check out Jeff McCune‘s talk, “Asynchronous Real-time Monitoring with MCollective.” If you’re looking to:

  • Get an introduction to MCollective
  • Understand why asynchronous communication is important when monitoring
  • Discover the benefits of addressing machines by meta-data
  • Learn how to write a monitoring agent for MCollective in Ruby
  • Understand how to remediate performance issues with MCollective and Puppet
  • then this is the talk to attend. 1:00 on Wednesday in the Mission City room. Jeff wrote the MCollective chapter in Pro Puppet, so you know he knows what he’s talking about.

    In unrelated opportunities, we want to buy you a drink! Come join Puppet Labs, Wednesday 6/15 in the San Jose room at TechMart, right next door to the Santa Clara Convention Center from 4:00 until we run out of free beer and food (probably around 9). A bunch of our staff just happens to be in town for a work function and we’d love to buy you a couple of beers.


    View Puppet Labs at Techmart in a larger map

Pro Puppet: A Handy (Indexed) Guide

Posted on
By
Jeff McCune
in
Blog, General News, How to, MCollective, Open Source, Tips
Responses
4 Comments »

For about three years now (since basically 15 minutes after Pulling Strings with Puppet was released) James has been asked, “When is the 2nd edition coming out?” This is quickly followed by, “Why is the book so short?” And then the question one never gets sick of: “Why isn’t there an index?”

Well y’all can stop asking—Pro Puppet is here and shipping. This edition is a complete rewrite and extension of the original book. It covers the 2.6.x series of releases and covers a lot more ground than the heavily space-limited Pulling Strings book.

The book includes quite a bit of material. The first two chapters re-introduce the reader to Puppet and provide step-by-step instructions to get a Puppet Master and Agent up and managing some resources. Puppet modules and organizing your code are also covered in these two chapters to help you get things nice and organized from the beginning. Since James is a fairly organized and sane person (and doesn’t separate out his right and left socks within pairs like Jeff does), he wrote these chapters with just the right attention to detail. Chapter 3 builds upon the organizational structure James introduces in the form of modules by covering Puppet environments. The chapter is actually more of a description of a typical dev/test/prod change management workflow with version control underlying the whole process. In Chapter 4, Jeff tackles scalability with Puppet by replacing the out-of-box Puppet Master with a full blown SSL load balancer enabling horizontal scaling by adding as many Puppet Masters as you’d like. If you’re interested in encryption, HTTP load balancing, and scalability then this chapter is definitely for you.

Following the scalability chapter, the rest of the book covers a number of different features of Puppet added since Pulling Strings. First, external node classification, which is really just a fancy term for “pulling in data from anywhere you want” is covered in a great chapter written by James. Next, Jeff covers the ability to exchange resources between Puppet managed nodes in the chapter about how to export resources from one node and collect them on another. If you’ve ever been annoyed by SSH host key warning messages or prompts, read this section. You should never again have to press “enter” before connecting to a host for the first time. Think of the time you’ll save!

Finally, a number of tools external to the core Puppet project are covered in the rest of the book. We cover how to setup and connect the Puppet Dashboard, providing a nice web interface to Puppet and the reports produced by Puppet runs. Other tools covered are the Puppet Forge and Puppet module tool, reports and custom report processors, Cucumber Puppet and the Ruby DSL. One tool in particular, MCollective, works incredibly well in combination with Puppet. It works so well, in fact, that an entire chapter has been dedicated to the subject of integrating MCollective for use with Puppet. If you’ve ever said to yourself, “Boy, I really wish I could make this change to all of those systems _right now_ but I hate having to know their hostnames to SSH into them,” then MCollective is something you should definitely check out in Chapter 11.

So why did it take so long? Well life, mostly, and waiting for the right release to base the book on. Thankfully this book was a collaboration with the awesome Jeff McCune, who unlike the book’s other author, James Turnbull, isn’t a shocking procrastinator. It was largely due to Jeff coming on board and writing half the book that the book got done at all.

Preview

Get the Book

Puppet + MCollective make for Quick Inventory Queries (Part 2 of 2)

Posted on
By
Gary Larizza
in
Blog, Community, How to, MCollective
Responses
1 Comment »

Check out Part 1 of this post here.

Using MCollective to Query Your Nodes

MCollective is an awesome solution for accessing information from all of your nodes very quickly. MCollective has a facter plugin that can pull fact information out of facter, but there’s a method that Jordan Sissel devised for exporting all of your facter facts (as well as all of the variables in the puppet scope) to a YAML file (specifically, /etc/mcollective/facts.yaml). Setting this up is pretty trivial (it’s a single-line inline template), and the benefits are exponential; not only is this MUCH faster than querying facter, but, as I mentioned, it pulls all of your variables out of the puppet scope in which you declared the /etc/mcollective/facts.yaml file. Follow the instructions in that link and let’s setup the /etc/mcollective/facts.yaml file.

Once you’ve set this up, let’s make sure MCollective is able to read from the file. This can be set in your /etc/mcollective/server.cfg config file with the following:

        factsource = yaml
	plugin.yaml = /etc/mcollective/facts.yaml

Next, we need to install a plugin so MCollective can handle YAML files as a factsource. The yaml_facts.rb file is included as a plugin with the MCollective source, but it can also be downloaded from the PuppetLabs Github site. Drop this file into your MCollective library’s facts folder (usually /usr/libexec/mcollective/mcollective/facts), ensure that the factsource is set in your server.cfg config file, and restart MCollective to test it out. You can execute “mc-inventory (hostname)” to test and make sure that facts are being reported properly.

With MCollective up and running and reading facts directly from a YAML file, let’s run a sample query with “mc-facts warranty_out” and see what we get:

        Report for fact: warranty_out
 
	        No                                      found 38 times
	        Yes                                     found 75 times
 
	Finished processing 113 / 113 hosts in 1047.24 ms

If you remember, this fact tells us if our machine’s warranty has expired. In this test with 113 nodes, you can see that 75 nodes have expired warranties and 38 nodes are currently under warranty. Next, let’s look at the expiration date for our warranties with “mc-facts warranty_end”:

        Report for fact: warranty_end
 
	        2011.02.23                              found 4 times
	        2011.04.30                              found 1 times
	        2011.07.14                              found 23 times
	        2011.07.15                              found 3 times
	        2011.07.16                              found 2 times
	        2011.07.17                              found 2 times
	        2011.07.19                              found 16 times
	        2011.09.16                              found 2 times
	        2012.09.15                              found 5 times
	        Expired                                 found 123 times
 
	Finished processing 183 / 183 hosts in 3098.34 ms

Here’s a larger sampling of nodes with several warranty expiration dates. This is all great information, but wouldn’t it be nice to see exactly WHICH nodes are corresponding to these dates. You can do that by running “mc-facts warranty_end -v”. The -v argument will list nodes corresponding to each fact underneath that fact in your output:

        2012.09.15                              found 4 times
 
	            berry-shawstaff-shel
	            deville-staff-wes
	            kluding-staff-shel
	            solomon-staff-shel

You can repeat this command with ANY fact. Since I am using the YAML solution as a factsource, it’s also exporting variables from my puppet scope. I have several variables associated with packages that are to be installed, and these package reside in the same scope as the /etc/mcollective/facts.yaml file declaration, so I can also query these variables with “mc-facts (variablename)”

        Report for fact: firefox
 
	        firefox3.6.11.dmg                       found 218 times
 
	Finished processing 247 / 247 hosts in 3027.37 ms

NOTE: Pay attention to the scope where you declare the /etc/mcollective/facts.yaml file. If this file is declared within the scope of its own class, you won’t see variables OUTSIDE its scope. You can do creative things to change the scope of this file if you wish (possibly using puppet-concat), but I’ll leave that up to you.

What About Offline Nodes?

MCollective works great for nodes that are online and connecting to your middleware solution (ActiveMQ, RabbitMQ, etc.), but what about machines such as laptops (or machines that have hardware failures) that might not be online? Fortunately, your puppet master server keeps a YAML store of fact data for all nodes that have ever connected to it. Located in your puppet master’s $vardir/yaml/facts directory, there’s a YAML file (identified by $certname) for every node. Writing a script to traverse the directory and query the nodes is pretty trivial—you can even create an MCollective Agent to do the task for you. Let’s look at a ruby script I created to search the YAML store:

        #!/usr/bin/env ruby
	#
	# File:			yaml_store_search.rb
	#
	# Description:	A script to search through your puppet master's YAML store
	#				 for a specific node's data.
 
	require 'getoptlong'
	require 'puppet'
 
	Puppet.settings.parse
 
	if not ARGV[0]
	  puts "You must have an argument.  Use --help for more information."
	  exit(1)
	end
 
	# Parse the arguments here and print the help prompt if any incorrect arguments
	#  are being used.
	opts = GetoptLong.new(
	    [ '--hostname', '-n', GetoptLong::REQUIRED_ARGUMENT],
	    [ '--certname', '-c', GetoptLong::REQUIRED_ARGUMENT],
	    [ '--help', '-h', GetoptLong::NO_ARGUMENT]
	)
 
	begin
	  opts.each do |opt, arg|
	      case opt
	          when '--hostname'
	              $hostname = arg
	          when '--certname'
	              $certname = arg
	          when '--help'
	              puts <<-EOF
	              yaml_store_search.rb [OPTION] value
 
	              -n, --hostname:
	                Search for a specific hostname in the YAML store. Requires a hostname argument
 
	              -c, --certname:
	                Search for a specific certname in the YAML store. Requires a certname argument
 
	              -h, --help:
	                Display this help text
 
	                EOF
	          end
	        end
	rescue GetoptLong::InvalidOption, GetoptLong::AmbigousOption
	  puts <<-EOF   
 
	  -n, --hostname:
	    Search for a specific hostname in the YAML store. Requires a hostname argument
 
	  -c, --certname:
	    Search for a specific certname in the YAML store. Requires a certname argument
 
	  -h, --help:
	    Display this help text
 
	    EOF
	  exit(1)
	end
 
	# Determine whether we're doing a lookup via hostname or certname
	searchfield = 'hostname' and arg = $hostname if $hostname
	searchfield = 'certname' and arg = $certname if $certname
 
	# Iterate through your puppet YAML store using the $vardir from
	#  your puppet.conf settings. If we find the YAML file with a
	#  matching certname or hostname, break out of the loop.
	Dir.glob("#{Puppet[:vardir]}/yaml/facts/*") {|file|
	  $tempfile = YAML::load_file(file).values
	  if $tempfile[searchfield] == arg
	    $found_file = true
	    break
	  end
	}
 
	# Output the list of facts.
	if $tempfile
	  $tempfile.each_pair {|key, value|
	    puts "#{key} = #{value}"
	  }
	end

This script will gather the value of your $vardir and will search the $vardir/yaml/facts directory in search of a node by way of its hostname or certname. If the node was found, it will output every fact that it has kept about that node. This script will ONLY work on puppet masters as they’re the only machines who keep this YAML store.

Since we’re talking about MCollective, let’s look at an MCollective Agent that will execute this code on your puppet master. Here’s the sample agent I created:

        module MCollective
	    module Agent
	        class Yaml_store "yaml_store.rb",
	                          :description => "A conduit to search your puppet master's YAML store.",
	                          :author      => "Gary Larizza ",
	                          :license     => "Apache License, Version 2.0",
	                          :version     => "1.0",
	                          :url         => "http://glarizza.posterous.com",
	                          :timeout     => 3
 
	              # Search action:  This action will check for the YAML file of a specified certname or hostname.
	              # =>               If the file exists, it will output the contents of the YAML file. If it
	              # =>               doesn't exist, you will receive an error message.
	              # Variables:
	              # =>              fact  => The fact for which we're checking a value
	              # =>              value => The value for which we're searching
	              # Calling:
	              # =>              Run the fact with 'mc-rpc --agent yaml_store --action search --arg hostname=lab01-hsimaclab-hhs -v'
	              # =>               or with 'mc-rpc --agent yaml_store --action search --arg certname=lab01-hsimaclab-hhs -v'
	              # =>               or with 'mc-rpc --agent yaml_store --action search --arg certname=lab01-hsimaclab-hhs --arg fact=warranty_end -v'
	              # 
 
	              action "search" do
 
	                if request.include?(:hostname)
	                  if request.include?(:fact)
	                    searchfield = 'hostname'
	                    arg = request[:hostname]
	                    reply[:facts] = get_specific_fact(searchfield, arg, request[:fact])
	                  else
	                    searchfield = 'hostname'
	                    arg = request[:hostname]
	                    reply[:facts] = get_all_facts(searchfield, arg)
	                  end
	                elsif request.include?(:certname)
	                  if request.include?(:fact)
	                    searchfield = 'certname'
	                    arg = request[:certname]
	                    reply[:facts] = get_specific_fact(searchfield, arg, request[:fact])
	                  else
	                    searchfield = 'certname'
	                    arg = request[:certname]
	                    reply[:facts] = get_all_facts(searchfield, arg)
	                  end
	                end
 
	              end # Action end
 
	                def get_all_facts(searchfield, arg)
	                  Dir.glob("#{Puppet[:vardir]}/yaml/facts/*") {|file|
	                    $tempfile = YAML::load_file(file).values
	                    if $tempfile[searchfield] == arg
	                      $found_file = true
	                      break
	                    end
	                  }
 
	                  if $found_file
	                    $tempfile.each_pair{|key, value|
	                      puts "#{key} = #{value}"
	                    }
	                  else
	                    puts "That #{searchfield} was not found."
	                  end
 
	                end # Def end
 
	                def get_specific_fact(searchfield, arg, thefact)
	                  Dir.glob("#{Puppet[:vardir]}/yaml/facts/*") {|file|
	                    $tempfile = YAML::load_file(file).values
	                    if $tempfile[searchfield] == arg
	                      $found_file = true
	                      break
	                    end
	                  }
 
	                  if $found_file
	                    if $tempfile[thefact]
	                      puts "#{thefact} = #{$tempfile[thefact]}"
	                    else
	                      puts "#{thefact} is not a valid fact, or wasn't found."
	                    end
	                  else
	                    puts "That #{searchfield} was not found."
	                  end
 
	                end # Def end
 
	        end # Class Etc_facts end
 
	  end # Module Agent end
 
	end # Module MCollective end

This agent will accept an argument of a node’s hostname or certname and also, optionally, a specific fact whose value we would want to inspect. I’ve also created a DDL file that will parse the output of this agent properly. Here’s that DDL file:

        metadata                :name        => "Yaml Store",
				:description => "A conduit to search your puppet master's YAML store",
				:author      => "Gary Larizza ",
				:license     => "Apache License, Version 2.0",
				:version     => "1.0",
				:url         => "http://glarizza.posterous.com",
				:timeout     => 60
 
	action "search", :description => "Retrieves Facter facts for specified nodes" do
	    display :always
 
	    input :hostname,
	          :prompt      => "Hostname",
	          :description => "The hostname of the node for which we're getting facts",
	          :type        => :string,
	          :optional    => true,
			  :validation  => '(.*?)',
	          :maxlength   => 230
 
		input :certname,
	          :prompt      => "The Puppet Certname Variable",
	          :description => "The certname of the node for which we're getting facts",
	          :type        => :string,
	          :optional    => true,
			  :validation  => '(.*?)',
	          :maxlength   => 230
 
		input :fact,
	          :prompt      => "A Searchable Facter Fact",
	          :description => "The facter fact for which we want a value",
	          :type        => :string,
	          :optional    => true,
	 	      :validation  => '(.*?)',
	          :maxlength   => 230
 
	    output 'facts',
	          :description => "The Facter facts you want displayed",
	          :display_as  => "Fact Information"
	end

In order for this agent to work, your puppet master must also be running MCollective and the agent and DDL file must be located in your MCollective library’s agent folder (typically /usr/libexec/mcollective/mcollective/agent). Once you’ve dropped these files into the agent folder, you’ll need to restart MCollective for it to work. Here’s the syntax you will use to run it:

        mc-rpc --agent yaml_store --action search --arg hostname=machine_hostname
        mc-rpc --agent yaml_store --action search --arg certname=machine_certname
	mc-rpc --agent yaml_store --action search --arg hostname=machine_hostname --arg fact=facter_fact
	mc-rpc --agent yaml_store --action search --arg certname=machine_hostname --arg fact=facter_fact
 
        # Or Simplified:
        mc-rpc yaml_store search hostname=machine_hostname
        mc-rpc yaml_store search certname=machine_certname fact=facter_fact

You can run this command from ANY MCollective client so long as the agent is installed on your puppet master server. The catch is that if you want the client to have the output parsed correctly, they will need to have ONLY the DDL file dropped into their MCollective library’s agent folder (the agent file itself is only needed on the puppet master server). If the client DOESN’T have the DDL file installed, they can simply append “-v” at the end of the above commands to see output from the reply hash that is used to communicate with the DDL file.

This agent will return either the entire list of facts for your specified hostname/certname or, optionally, the value of a specific fact. This is useful if your machine has malfunctioned (or is offline) and you quickly want to access whether the warranty has expired or not. Being able to access it from an MCollective client who has access to mc-rpc is handy if you’re not currently on your work computer. This access, however, is entirely up to you.

In Conclusion

If you’re familiar with MCollective and Puppet (and you have a functional understanding of Ruby), it’s pretty easy to write custom Facter facts and MCollective agents to automate simple tasks. The process of maintaining an inventory can be particularly troublesome, but these scripts should give you near-immediate access to some of the most important facts about your Macs. Like I mentioned in the opening, most vendors will provide you with a conduit to access similar information to facts I’ve presented here for my Macs. All it will take is a bit of tweaking to adapt my code for your use. Keep pulling those strings!

Gary Larizza is the Director of Technology for a small K-12 School district in Northern Ohio where he routinely breaks systems in the name of advancement. When he’s not trying to automate himself out of a job through the use of Puppet and Ruby, he enjoys seeking out awesome open source tools that will make Mac Management easier. He’s been using Puppet in the Education sector for the past two years on hardware that would make Linux admins cry (namely, G5 Xserves and an iMac) and loves to share the knowledge he’s gained with anyone who buys him a wheat beer (Weihenstephaner FTW). All of his notes are on his Posterous blog, and he will be speaking at the 2011 Penn State University Macadmins Conference if you’d prefer to chat with him in-person.

Guest Post: Puppet + MCollective make for Quick Inventory Queries (Part 1 of 2)

Posted on
By
Gary Larizza
in
Blog, Community, How to, MCollective
Responses
1 Comment »

Mac Inventory/Warranty Lookups with MCollective

Maintaining an accurate inventory of all of your machines is an oft-neglected evil for IT staff. Knowing when a machine was purchased and, more importantly, if it’s still under warranty is often overlooked until something malfunctions. Most vendors provide a way to access the machine’s serial number programmatically, and many of them provide a web conduit to provide purchase and warranty information. This article will step you through setting this process up on a Mac running OS X.

Custom Facts for Warranty Information

The first part of this equation is to create custom facts that will provide us with the following:

  1. The purchase date
  2. If our warranty is currently valid
  3. The warranty expiration date
  4. A description of the machine

To get this information, we pull the Serial Number using the /usr/sbin/system_profiler binary and then query Apple’s Self Servicing site for all the relevant information. Here’s what the Facter fact looks like: Access the full fact here.

        require 'facter'
	require 'open-uri'
	require 'openssl'
 
	# Constraining to the Darwin Kernel - it's only useful for Macs
	if Facter.value('kernel') == 'Darwin'
	  warranty_array = []
	  hash = {}
	  sn  = %x{system_profiler SPHardwareDataType | awk -F": " '/Serial/{print $2}'}
	  open('https://selfsolve.apple.com/warrantyChecker.do?sn=' + sn.upcase + '&country=USA') {|item|
	         item.each_line {|item|}
	         warranty_array = item.strip.split('"')
	         warranty_array.each {|array_item|
	           hash[array_item] = warranty_array[warranty_array.index(array_item) + 2] if array_item =~ /[A-Z][A-Z\d]+/
	         }
	  }
	end
 
	Facter.add("purchase_date") do
	  confine :kernel => "Darwin"
	  setcode do
	    hash['PURCHASE_DATE'].gsub("-",".")
	  end
	end
 
	Facter.add("warranty_out") do
	  confine :kernel => "Darwin"
	  setcode do
	    (hash['HW_COVERAGE_DESC'] == 'Out of Warranty') ? "Yes" : "No"
	  end
	end
 
	Facter.add("warranty_end") do
	  confine :kernel => "Darwin"
	  setcode do
	    (!hash['COV_END_DATE'].empty?) ? hash['COV_END_DATE'].gsub("-",".") : "Expired"
	  end
	end
 
	Facter.add("product_description") do
	  confine :kernel => "Darwin"
	  setcode do
	    hash['PROD_DESCR'].chomp
	  end
	end

The four facts that we pull are “purchase_date”, “warranty_out”, “warranty_end”, and “product_description”. Just having these facts is beneficial, but now we need a method to query them on active machines. MCollective provides an excellent conduit for these queries using the mc-facts and mc-find-host binaries. Let’s take a look and see how this works.

In the next post, I will expand on this custom fact by showing how to use MCollective to receive immediate feedback from all of your nodes (whether online or offline).

Continue with Part 2 of this post here.

Gary Larizza is the Director of Technology for a small K-12 School district in Northern Ohio where he routinely breaks systems in the name of advancement. When he’s not trying to automate himself out of a job through the use of Puppet and Ruby, he enjoys seeking out awesome open source tools that will make Mac Management easier. He’s been using Puppet in the Education sector for the past two years on hardware that would make Linux admins cry (namely, G5 Xserves and an iMac) and loves to share the knowledge he’s gained with anyone who buys him a wheat beer (Weihenstephaner FTW). All of his notes are on his Posterous blog, and he will be speaking at the 2011 Penn State University Macadmins Conference if you’d prefer to chat with him in-person.

Using MCollective 1.1.3 Subcollectives for Security

Posted on
By
R.I. Pienaar
in
Blog, How to, MCollective, Tips
Responses
0 Comments

We’ve released The Marionette Collective version 1.1.3 on Monday that introduced a major new feature called Subcollectives. This feature lets you partition your collective into multiple isolated broadcast zones much like a VLAN does to a traditional network. Each node can belong to one or many collectives at the same time.

An interesting side effect of this feature is that you can create subcollectives to improve security of your network. I’ll go through a process here for providing untrusted 3rd parties access to just a subset of your servers.

The image above demonstrates a real world case where a customer wanted to control their machines using the abilities exposed by MCollective on a network hosting servers for many customers.

The customer has a CMS that creates accounts on his backend systems, sometimes he detects abuse from a certain IP and need to be able to block that IP from all his customer facing systems immediately. We did not want to give the CMS access to SSH as root to the servers to we provided a MCollective Agent that expose this ability using SimpleRPC.

Rather than deploy a new collective using different daemons, we use the new Subcollectives features to let the customer machines belong to a new collective called custcollective while still belonging to the existing collective. We then restrict the user at the middleware layer and set his machines up to allow him access to them via the newly created collective.

To properly secure this setup we give the customer their own username on the ActiveMQ server and secure it so it can only communicate with his subcollective:

<simpleAuthenticationPlugin>
  <users>
    <authenticationUser username="customer" password="secret" groups="customer,everyone"/>
  </users>
</simpleAuthenticationPlugin>
 
<authorizationPlugin>
  <map>
    <authorizationMap>
        <authorizationEntries>
          <authorizationEntry topic="custcollective.>" write="mcollectiveusers,customer" read="mcollectiveusers,customer" admin="mcollectiveusers,genzee" />
        </authorizationEntries>
    </authorizationMap>
  </map>
</authorizationPlugin>

This sets up the namespace for the custcollective and give the user access to it, we only give him access to his collective and no others.

Next we have to configure the customers servers to belong to the new collective in addition to the existing collective using their server.cfg:

collectives = collective,custcollective
main_collective = collective

And finally we give the customer a client.cfg that limits him to this collective:

collectives = custcollective
main_collective = custcollective
 
plugin.stomp.pool.user1 = customer
plugin.stomp.pool.password1 = secret

Due to the restrictions on the middleware level, even if the customer were to specify other collective names in his client.cfg, he would not be able to communicate with those hosts.

We now setup Authorization to give the user access to just the agents and actions you authorize him to communicate with. A sample policy file using the Action Policy Authorization Plugin can be seen below, it lets the user use the iptables agent block action on just his machines while allowing me to use all actions on all machines:

policy default deny
allow   cert=rip        *       *               *
allow   cert=customer   block   customer=acme   *

And finally thanks to the Auditing built into MCollective the clients actions are fully logged:

2011-03-05T21:03:52.598552+0000: reqid=ebf3c01fdaa92ce9f4137ad8ff73336b: 
reqtime=1299359032 caller=cert=customer@some.machine agent=iptables 
action=block data={:ipaddr => "196.xx.xx.146"}

The customer is happy as he was able to build a real time IDS that reacts to events throughout his network, he can interact with it from CLI, automated IDS, and even his web systems.

Using this technique and combining it with the existing AAA in MCollective, we as an ISP were able to expose a subset of machines to an untrusted 3rd party in a way that is safe, secure and audited without having to give the 3rd party elevated or even shell access to these machines.

This post originally appeared on devco.net.

The Marionette Collective Version 1.1.3

Posted on
By
R.I. Pienaar
in
Blog, Community, MCollective, product release
Responses
0 Comments

We are pleased to announce the release 1.1.3 of The Marionette Collective.

This release is part of the development series and should be used by early adopters.

MCollective 1.1.3 offers a major new feature and numerous bug fixes:

Enhancements:

Bug Fixes:

  • Missing libdirs does not cause silent crashes anymore.
  • MCOLLECTIVE_EXTRA_OPTS are correctly parsed.
  • Middleware connectivity has been made more robust.

Full release notes are available and the files are in our usual downloads section.