Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Import nv_helpers after 'bundle gem'

  • Loading branch information...
commit 54dbcf422878564ac2525593f44ab63b986cbd13 0 parents
Damian Martinez porcupie authored
4 .gitignore
@@ -0,0 +1,4 @@
+*.gem
+.bundle
+Gemfile.lock
+pkg/*
4 Gemfile
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in nv_helpers.gemspec
+gemspec
2  Rakefile
@@ -0,0 +1,2 @@
+require 'bundler'
+Bundler::GemHelper.install_tasks
48 Rakefile.orig
@@ -0,0 +1,48 @@
+require 'tempfile'
+
+#VERSION = "1.0.1"
+BUILDROOT = '/var/tmp/nv_helpers-buildroot/'
+
+desc 'Build an etch client RPM on a Red Hat box'
+task :redhat => [:redhatprep, :rpm]
+desc 'Prep a Red Hat box for building an RPM'
+task :redhatprep do
+ # Install the package which contains the rpmbuild command
+ system('rpm --quiet -q rpm-build || sudo yum install rpm-build')
+end
+desc 'Build an etch client RPM'
+task :rpm do
+ #
+ # Create package file structure in build root
+ #
+
+ rm_rf(BUILDROOT)
+ libdir = File.join(BUILDROOT, 'usr', 'lib', 'ruby', 'site_ruby', '1.8', 'nv_helpers')
+ mkdir_p(libdir)
+ cp('nv_helpers/node_group_helper.rb', libdir)
+ cp('nv_helpers/graffiti_helper.rb', libdir)
+ cp('nv_helpers/nv_wrapper.rb', libdir)
+ cp('nv_helpers.rb', File.dirname(libdir))
+
+ #
+ # Prep spec file
+ #
+ spec = Tempfile.new('nv_helpersrpm')
+ IO.foreach('nv_helpers.spec') do |line|
+# line.sub!('%VER%', VERSION)
+ spec.puts(line)
+ end
+ spec.close
+
+ #
+ # Build the package
+ #
+
+ system("rpmbuild -bb --buildroot #{BUILDROOT} #{spec.path}")
+
+ #
+ # Cleanup
+ #
+
+ rm_rf(BUILDROOT)
+end
15 example.rb
@@ -0,0 +1,15 @@
+require 'nv_helpers'
+
+helper = NvHelpers::NvWrapper.new
+
+puts helper.get_nodes_from_group("qa-r1-singles-webapp").inspect
+puts helper.parse_node_group("qa-r1-jazzed:account").inspect
+
+# Get all graffitis of this nodegroup
+puts helper.get_graffitis("qa-ddao-singles-webapp").inspect
+
+# Specify what graffitis you want to get
+puts helper.get_graffitis("qa-ddao-singles-webapp", ["service_name", "instances"]).inspect
+
+puts helper.get_node_by_name("nonexistingnode.com").inspect
+puts helper.get_node_by_name("devssvm.dev.dc1.eharmony.com").inspect
3  lib/nv_helpers.rb
@@ -0,0 +1,3 @@
+module NvHelpers
+ # Your code goes here...
+end
3  lib/nv_helpers/version.rb
@@ -0,0 +1,3 @@
+module NvHelpers
+ VERSION = "0.0.1"
+end
21 nv_helpers.gemspec
@@ -0,0 +1,21 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "nv_helpers/version"
+
+Gem::Specification.new do |s|
+ s.name = "nv_helpers"
+ s.version = NvHelpers::VERSION
+ s.platform = Gem::Platform::RUBY
+ s.authors = ["TODO: Write your name"]
+ s.email = ["TODO: Write your email address"]
+ s.homepage = ""
+ s.summary = %q{TODO: Write a gem summary}
+ s.description = %q{TODO: Write a gem description}
+
+ s.rubyforge_project = "nv_helpers"
+
+ s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.require_paths = ["lib"]
+end
4 nv_helpers.rb
@@ -0,0 +1,4 @@
+$:.unshift(File.join(File.dirname(__FILE__), 'nv_helpers'))
+require 'graffiti_helper'
+require 'node_group_helper'
+require 'nv_wrapper' # Need to be last
18 nv_helpers.spec
@@ -0,0 +1,18 @@
+Summary: helper scripts for dealing with nVentory
+Name: nv_helpers
+Version: 1.1
+Release: 1
+License: Proprietary
+Group: System/Tools
+URL: http://www.eharmony.com/
+Requires: ruby, nventory-client
+BuildRoot: %{_builddir}/%{name}-buildroot
+BuildArch: noarch
+
+%description
+This package includes helper scripts for dealing with nVentory
+
+%files
+%defattr(-,root,root)
+/usr/lib/ruby/site_ruby/1.8/nv_helpers/*.rb
+/usr/lib/ruby/site_ruby/1.8/nv_helpers.rb
34 nv_helpers/graffiti_helper.rb
@@ -0,0 +1,34 @@
+module NvHelpers
+ module GraffitiHelper
+ # Returns a hash of key => value graffiti(s)
+ # If user doesn't specify what graffitis, then return all graffitis
+ def get_graffitis(node_group, keys = nil, recursive = false)
+ result = {}
+ data = get_node_group_by_name(node_group, {:includes => ['graffitis', 'parent_groups']})
+
+
+ data['graffitis'].each do | graffiti |
+ if keys.nil? or keys.include?(graffiti['name'])
+ result[graffiti['name']] = graffiti['value']
+ end
+ end
+
+ # See if we got all of the graffitis we need.
+ # If not, then try to find it from the parent nodegroups
+ if keys
+ leftover = keys - result.keys
+ else
+ leftover = nil
+ end
+ unless leftover.nil? or leftover.empty? or !recursive
+ parents = data["parent_groups"].collect{|pg|pg['name']}
+ parents.each do |parent|
+ # TODO: do we want to keep on traversing up the tree? If not,
+ # then we need to call get_graffitis with false
+ result.merge!(get_graffitis(parent, leftover, true))
+ end
+ end
+ result
+ end
+ end
+end
64 nv_helpers/node_group_helper.rb
@@ -0,0 +1,64 @@
+module NvHelpers
+ module NodeGroupHelper
+ def parse_node_group(node_group)
+ result = {}
+ envs = ['prod', 'qa', 'stage', 'dev', 'dyn', 'np', 'ee', 'lt']
+
+ # First, split by the : character
+ tokens = node_group.split(":")
+
+ # Use case 1: nodegroup has the name format of x
+ if tokens.size == 1
+ if envs.include?(tokens[0])
+ result[:env] = tokens[0]
+ else
+ # No idea
+ raise "I'm not smart enough to parse this nodegroup name."
+ end
+ return result
+ elsif tokens.size != 2
+ raise "unknown nodegroup format"
+ end
+
+ # Use case 2: nodegroup has the name format of x:y
+ result[:service] = tokens[1]
+ env_product = tokens[0]
+ tokens = env_product.split("-")
+ if envs.include?tokens[0]
+ result[:env] = tokens[0]
+ end
+
+ if result[:env] == "qa" && tokens[1] =~ /r\d+/
+ result[:runway] = tokens[1]
+ tokens.delete(result[:runway])
+ end
+ tokens.delete(result[:env])
+
+ if tokens.size == 1
+ result[:product] = tokens[0]
+ elsif tokens.size > 1
+ result[:runway] = tokens[0]
+ tokens.delete(result[:runway])
+ result[:product] = tokens.join("-")
+ end
+ return result
+ end
+
+ # takes in env, runway, product, service and figure out
+ # the corresponding node group
+ def whats_my_node_group(data={}, service_delimeter=":")
+ env = data[:env]
+ runway = data[:runway]
+ if data[:product] == "shared" or data[:product] == ""
+ product = nil
+ else
+ product = data[:product]
+ end
+ service = data[:service]
+ env_prod = [env, runway, product].compact.join("-")
+ env_prod = nil if env_prod.empty?
+ node_group = [env_prod, service].compact.join(service_delimeter)
+ return node_group
+ end
+ end
+end
123 nv_helpers/nv_wrapper.rb
@@ -0,0 +1,123 @@
+require 'nventory'
+
+module NvHelpers
+ # Wrapper class for querying nVentory
+ class NvWrapper
+ include GraffitiHelper
+ include NodeGroupHelper
+
+ def initialize(nv_config={})
+ # nventory client config hash uses symbol. Make sure we convert all
+ # the keys to symbols
+ @nv_config = nv_config.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
+ @nv_config[:server] ||= "http://nventory.corp.eharmony.com"
+ if @nv_config[:server] !~ /^http/
+ @nv_config[:server] = "http://" + @nv_config[:server]
+ end
+ @username = @nv_config[:username]
+ @password = @nv_config[:password]
+
+ @nvclient = NVentory::Client.new(@nv_config)
+ end
+
+ def set_nv_server_url(url)
+ @nv_config[:server] = url
+ @nvclient = NVentory::Client.new(@nv_config)
+ end
+
+ def method_missing method_id, *args
+ @nvclient.send(method_id, *args)
+ end
+
+ def delete_objects(objecttypes, data)
+ @nvclient.delete_objects(objecttypes, data, @username, @password)
+ end
+
+ def delete_nodes(data)
+ delete_objects('nodes', data)
+ end
+
+ def get_objects(options)
+ # including all available fields
+ if options[:includeallfields]
+ includes_hash = {}
+ field_names = @nvclient.get_field_names(options[:objecttype])
+ field_names.each do |field_name_entry|
+ field_name, rest = field_name_entry.split(' ')
+ if field_name =~ /([^\[]+)\[.+\]/
+ includes_hash[$1] = true
+ end
+ end
+ includes ||= []
+ includes |= includes_hash.keys
+ options[:includes] = includes
+ end
+
+ objects = @nvclient.get_objects(options)
+ return objects
+ end
+
+ def get_nodes(options)
+ options[:objecttype] = 'nodes'
+ return get_objects(options)
+ end
+
+ # Returns nVentory data of nodegroup with the given name
+ def get_node_by_name(name, options={})
+ options[:exactget] ||= {}
+ options[:exactget][:name] = name
+ ret = get_nodes(options)
+ if ret.empty?
+ warn "Cannot find node #{name}"
+ ret = nil
+ elsif ret.values.size == 1
+ ret = ret.values[0]
+ else
+ raise "Multiple nodes returned for #{name}"
+ end
+ ret
+ end
+
+ # Returns nVentory data of nodegroup with the given id
+ def get_node_by_id(id, options={})
+ options[:exactget] ||= {}
+ options[:exactget][:id] = id.to_s
+ ret = get_nodes(options)
+ if ret.empty?
+ warn "Cannot find node #{name}"
+ ret = nil
+ elsif ret.values.size == 1
+ ret = ret.values[0]
+ else
+ raise "Multiple nodes returned for #{name}"
+ end
+ ret
+ end
+
+ # Returns hash of nodegroupname => nodegroupdata
+ def get_nodes_from_group(node_group, options = {})
+ options[:exactget] ||= {}
+ options[:exactget]['node_group[name]'] = node_group
+ options[:includes] ||= []
+ options[:includes] << ['status'] # we're always interested in status
+ return get_nodes(options)
+ end
+
+ # Returns nVentory data for the given nodegroup and option
+ def get_node_group_by_name(name, options = {})
+ options[:objecttype] = 'node_groups'
+ options[:exactget] ||= {}
+ options[:exactget][:name] = name
+ ret = get_objects(options)
+ if ret.empty?
+ warn "Cannot find node #{name}"
+ ret = nil
+ elsif ret.values.size == 1
+ ret = ret.values[0]
+ else
+ raise "Multiple nodes returned for #{name}"
+ end
+ ret
+ end
+ end
+end
68 tests/test_node_group_helper.rb
@@ -0,0 +1,68 @@
+$:.unshift File.join(File.dirname(__FILE__),'..')
+require 'nv_helpers/node_group_helper'
+require 'test/unit'
+
+class TestNodeGroupHelper < Test::Unit::TestCase
+ include NvHelpers::NodeGroupHelper
+ def test_parse_node_group
+ expect = {:env => "qa"}
+ result = parse_node_group("qa")
+ assert_equal(expect, result)
+
+ expect = {:env => "prod", :service => "service"}
+ result = parse_node_group("prod:service")
+ assert_equal(expect, result)
+
+ expect = {:env => "dev", :service => "webapp", :product => "singles"}
+ result = parse_node_group("dev-singles:webapp")
+ assert_equal(expect, result)
+
+ expect = {:env => "dyn", :service => "account", :product => "jazzed", :runway => "ddao"}
+ result = parse_node_group("dyn-ddao-jazzed:account")
+ assert_equal(expect, result)
+
+ expect = {:env => "qa", :service => "webapp", :product => "singles"}
+ result = parse_node_group("qa-singles:webapp")
+ assert_equal(expect, result)
+
+ expect = {:env => "qa", :service => "account", :product => "jazzed", :runway => "r1"}
+ result = parse_node_group("qa-r1-jazzed:account")
+ assert_equal(expect, result)
+
+ expect = {:service => "something3", :runway => "something", :product => "something2"}
+ result = parse_node_group("something-something2:something3")
+ assert_equal(expect, result)
+ end
+
+ def test_whats_my_node_group
+ data = {:product => "singles", :service => "webapp", :env => "prod"}
+ result = whats_my_node_group(data)
+ assert_equal("prod-singles:webapp", result)
+ result = whats_my_node_group(data, "-")
+ assert_equal("prod-singles-webapp", result)
+
+ data = {:product => "jazzed", :service => "account", :env => "qa", :runway => "r1"}
+ result = whats_my_node_group(data)
+ assert_equal("qa-r1-jazzed:account", result)
+
+ data = {:product => "jazzed", :service => "account", :env => "dev"}
+ result = whats_my_node_group(data)
+ assert_equal("dev-jazzed:account", result)
+
+ data = {:service => "hadoop"}
+ result = whats_my_node_group(data)
+ assert_equal("hadoop", result)
+
+ data = {:product => "jazzed", :service => "webapp"}
+ result = whats_my_node_group(data)
+ assert_equal("jazzed:webapp", result)
+
+ data = {:env => "qa", :product => "singles", :service => "webapp"}
+ result = whats_my_node_group(data)
+ assert_equal("qa-singles:webapp", result)
+
+ data = {:env => "qa", :product => "", :service => "webapp"}
+ result = whats_my_node_group(data)
+ assert_equal("qa:webapp", result)
+ end
+end
18 tests/test_nv_wrapper.rb
@@ -0,0 +1,18 @@
+require './nv_helpers'
+require 'test/unit'
+
+class TestNvWrapper < Test::Unit::TestCase
+ def test_initialize
+ assert_nothing_raised{ NvHelpers::NvWrapper.new }
+ assert_nothing_raised{ NvHelpers::NvWrapper.new({'server' => 'nventory.dev.corp.eharmony.com'}) }
+ assert_nothing_raised{ NvHelpers::NvWrapper.new({'server' => 'nventory.corp.eharmony.com'}) }
+ assert_nothing_raised{ NvHelpers::NvWrapper.new({'server' => 'nventory.dev.corp.eharmony.com', 'username' => 'ddao'}) }
+ assert_nothing_raised{ NvHelpers::NvWrapper.new({'server' => 'nventory.dev.corp.eharmony.com', 'username' => 'ddao', 'password' => 'secret'}) }
+ end
+ def test_get_nodes
+ nv_helper = NvHelpers::NvWrapper.new
+ result = nv_helper.get_nodes({:get => {:name => "prod.dc1.eharmony.com", 'network_interfaces[name]' => "eth0"},
+ :includes => ['network_interfaces[ip_addresses]']})
+ assert(!result.empty?)
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.