Had a case the other day where I needed to create users accounts in a specific fashion. If I had less then 25 users I would use letters for the test accounts (eg: usera, userb, ect), if there were more then 25 I would use numbered accounts (eg: user1, user2, ect ) The problem was there could be any number of user accounts and I wanted to keep to this schema.

Unfortunately Enumerable wasn’t going to make this as easy as most things are in ruby, like this wasn’t going to work:

"a".upto(5)

However I figured I could just switch to their ascii equivalent and then this would be easy!

  
num_of_users = 25
if num_of_users <= 25
  (97..97+num_of_users).each{|e| puts e.chr}
else
  num_of_users.times{|e| puts e}
end

Worked like a charm!

 

Upgrading to Chef Server ( 0.10.8 ) is dead simple, takes probably 30 seconds.

    for s in server server-webui solr expander; do sudo /etc/init.d/chef-${s} stop; done
     sudo gem update chef chef-server --no-ri --no-rdoc
    for s in server server-webui solr expander; do sudo /etc/init.d/chef-${s} start; done

If you want you can backup the server first using Seth’s backup script ( here ). Installing, and running it, is dead simple:

curl -O https://raw.github.com/jtimberman/knife-scripts/master/chef_server_backup.rb
knife exec chef_server_backup.rb

This will create a backup fo the server in your .chef dir. Enjoy

 

So here is my use case, I have a two nodes which have to be configured to know about each other, but I can’t use multicast, and I want to be elastic, in that I can add a node and the others configs get updated. So to start we are going to have two nodes, gateway1 and gateway2, and each has a config file called sipmethod.xml which contains a node of XML data that defines the cluster.

 <Cluster>
   <Node name="gateway2" local="10.72.111.116:47520">
      <Peer remote="10.110.234.150:47520"/>
   </Node>
 </Cluster>

and here is my template that creates this section (sorta):

  
<% if node[:prism][:sipmethod][:cluster] %>
 <Cluster>
   <Node name="<%=node[:hostname]%>" local="<%=node[:ipaddress]%>:<%= node[:prism][:sipenv][:rmi_port] %>">
     <% search(:node, "role:rayo_gateway AND chef_environment:#{node.chef_environment}").each do |peer| %>
      <Peer remote="<%= (peer.ec2 ? peer.ec2.local_ipv4 : peer.ipaddress) %>:<%= node[:prism][:sipenv][:rmi_port] %>"/>
     <%end%>
   </Node>
 </Cluster>
 <%end%>

Now there is one problem with this approach, if you look carefully the peers are going to include itself, which is not going to work.

 <Cluster>
   <Node name="gateway2" local="10.72.111.116:47520">
      <Peer remote="10.110.234.150:47520"/>
      <Peer remote="10.72.111.116:47520"/>  <!-- PROBLEM --> 
   </Node>
 </Cluster>

I need to not include the node running the search in the results, and this is actually pretty simple:

We are going to take this search and simply add a NOT clause:

 search(:node, "role:rayo_gateway AND chef_environment:#{node.chef_environment} NOT name:#{node.name}")

This will result in returning every gateway in my environment except the one running the search, and the end result is the dynamically configured cluster config:

 <Cluster>
   <Node name="gateway2" local="10.72.111.116:47520">
      <Peer remote="10.110.234.150:47520"/>
   </Node>
 </Cluster>
 

Dan Ryan has an awesome gem on Github called Spice , which is a nice wrapper to the Chef Severs RestAPI.  The one thing I didn’t find clearly documented was how to do a search based on things such as environment, roles, and run lists.  However after a bit of digging I was able to get this working and I felt obliged to share w/ the class. The first thing you need to do is setup the Spice connection.  This part of pretty straight forward and of course well documented:

Spice.setup do |s|
  s.server_url = "http://chef.server.net"
  s.client_name = "client-key"
  s.key_file = "#{File.dirname(__FILE__)}/keys/client-key.pem"
end

view raw test.rb This Gist brought to you by GitHub.

Then you perform the query using Spice.connection.get

results = Spice.connection.get('/search/node', :params => {:q => "role:base AND role:rayo_gateway AND chef_environment:ec2_rayo_functional_tests"})["rows"]

view raw file.rb This Gist brought to you by GitHub.

This will return a collection that you can easily iterate over to get the ‘goods’

require 'spice'

Spice.setup do |s|
  s.server_url = "http://chef.server.net"
  s.client_name = "client-key"
  s.key_file = "#{File.dirname(__FILE__)}/keys/client-key.pem"
end

results = Spice.connection.get('/search/node', :params => {:q => "role:base AND role:rayo_gateway AND chef_environment:ec2_rayo_functional_tests"})["rows"]

results.each do |node|
  puts node["automatic"]["ec2"]["public_ipv4"]
end

view raw snippet.rb This Gist brought to you by GitHub.

The great thing is this not only contains the node’s attributes and run lists but it also contains all the Ohai data for each node.  This is some powerful stuff, hope you enjoy!

© 2011 John T Dyer Suffusion theme by Sayontan Sinha