How to convert ruby dsl chef environment file to JSON format? - ruby

How can I convert chef environment file which has Ruby DSL format to json?
Is that possible?
I would like to use environment file attributes in a ruby script but I cannot parse it.
Are there any way to parse these .rb files?
Thanks,
Tomszy

You can do it the same way Chef does :)
https://github.com/chef/chef/blob/master/lib/chef/environment.rb
require 'chef'
Chef::Config[:environment_path] = '/path/to/directory/with/rb_file'
env = Chef::Environmment.load_from_file('environment_name') # ! => not filename!
env.to_json

I've used this ruby script to convert ruby DSL files to JSON.
#!/usr/bin/env ruby
envfilename = '/path/to/environment.rb'
rolefilename = '/path/to/role.rb'
role = Chef::Role.new
role.name(File.basename(rolefilename, ".rb"))
role.from_file(rolefilename)
File.open(rolefilename.gsub(".rb", ".json"),"w") {|f| f.puts(role.to_json)}
env = Chef::Environment.new
env.name(File.basename(envfilename, ".rb"))
env.from_file(envfilename)
File.open(envfilename.gsub(".rb", ".json"),"w") {|f| f.puts(env.to_json)}
I got this script by modifying the code I found here: https://knife-zero.github.io/tips/use_ruby_dsl_for_envs_or_roles/

Related

How do I get Ruby awesome_print to file?

I am trying to get awesome_print to output to a file rather than the console but I cant find out how to do this?
require "awesome_print"
mySymbolizedHash = {'blah' => 'blabbbb', 'this' => 'that'}
This will write to console, I need to write the formatted output to file.
If I write the hash directly to a file, its not formatted they way I want.
ap mySymbolizedHash
File.open('some_file', 'w') do |f|
f.write mySymbolizedHash.awesome_inspect
end
awesome_inspect seems undocumented, but ai seems to be an alias, and that's used all over the place.
You could redirect STDOUT to a file, as shown here:
http://stackoverflow.com/questions/1470344/outputting-stdout-to-a-file-and-back-again
awesome_print doesn't seem to return the value, so no assigning it to a variable :(

Getting recipe list through chef server api

I want to get the recipes that a cookbook contains, through chef-server-api. Following is the code I'm using for getting the cookbook list, individual cookbook details through the api :
require 'rubygems'
require 'chef/config'
require 'chef/log'
require 'chef/rest'
require 'chef/cookbook_version'
client_name = "admin"
signing_key_filename="c:/chef-repo/.chef/admin.pem"
server_url = "https://10.132.17.244:443"
rest = Chef::REST.new(server_url, client_name, signing_key_filename)
cookbooks = rest.get_rest("/cookbooks?all_versions")
cookbooks.keys.each do |name|
cookbook_versions = rest.get_rest("/cookbooks/#{name}")
print "#{name}\n"
cookbook_versions[name]["versions"].each do |cv|
version = cv["version"]
cookbook = rest.get_rest("/cookbooks/#{name}/#{version}")
print "\t#{cookbook}\n"
#parsed = JSON[cookbook]
end
end
The problem I'm facing is to get the recipe list from the 'cookbook' object. I tried parsing it to ruby hash and then read, but of no use. If I directly print the 'cookbook' variable, the output is something like the screenshot
I'm not able to get how to interpret the output I am getting by hitting the '/cookbooks/NAMEW/VERSION' endpoint, and get the recipes present in an individual cookbooks.
When using the Chef gem it automatically decodes some responses into Ruby objects for you. You can either use the object directly (specifically you want #recipe_filenames and then parse those to the cookbook_name::recipe_name format) or you could use a better API client like Chef-API or PyChef.
Need a ruby solution? The following example uses jq to filter the JSON resultset returned by knife:
$ knife cookbook show apache2 2.0.0 recipes -Fj | jq '.[]|.name'
"mod_cgi.rb"
"mod_proxy_http.rb"
"mod_proxy_html.rb"
"mod_access_compat.rb"
"mod_authz_dbd.rb"
"mod_proxy_express.rb"
..
..

how to convert data URI to file in Ruby

How do I convert a data URI that comes from the result of the FileReader API into an image file that can be saved in the file system in Ruby?
What I'm currently trying to do is using base64 decode to convert the data_uri string which looks like this: data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgA... into base 64 encoded string because according to this stackoverflow answer I need to replace all the instances of spaces into +. The answer is in PHP but I'm currently working on Ruby and Sinatra so I'm not sure if it still applies, but when using the equivalent code:
src = data_uri.gsub! ' ', '+'
src = Base64.decode64(src)
f = File.new('uploads/' + 'sample.png', "w")
f.write(src)
f.close
I get the following error:
undefined method `unpack' for nil:NilClass
What I'm trying to achieve here is to be able to convert the data URI to a file.
There's no need to reinvent the wheel. Use the data_uri gem.
require 'data_uri'
uri = URI::Data.new('data:image/gif;base64,...')
File.write('uploads/file.jpg', uri.data)

Accessing info about rubygem from within ruby script

I need to get the installation path for a given ruby gem and can't find any information on how to do that. Given:
#!/usr/bin/env ruby
require 'rubygems'
require 'somegem'
How can I find out where the installation path of somegem is on the system (without resorting to system(gem ...). The gem in question comes with some icons which I want to reference in my script.
Thanks to Chris I now have the following assembled:
require 'rubygems/Commands/contents_command'
c = Gem::Commands::ContentsCommand.new
c.options[:args] = 'somegem'
c.execute
However, c.execute immediately outputs the result on stdout. How can I catch that in a variable for further processing? res = c.execute does not work.
You have different ways to achieve this:
Gem.source_index.find_name('somegem').last.full_gem_path
You could also just grep your load path:
$:.grep /somegem/

Add Ruby Source Code as HTML to RDoc

How do I include a ruby code file, as is, into RDoc?
I have an example.rb file that documents how to use my gem and I would like to include that as one of the files like the README.rdoc and HISTORY.rdoc.
I've already figured out how to convert the ruby source code into HTML using the Syntax gem but I can't figure out how to make RDoc include the file without parsing it.
When I tell RDoc to include the html file it isn't listed and if I fake it out by using rdoc or txt as the file extension it doesn't display properly (the file is still actually html).
I've got a solution that works it's just incredibly ugly. There has got to be a better way to do this that's native to rdoc but I don't see it.
Here's what I have in my Rakefile:
# Build rdocs
require 'rake/rdoctask'
require 'syntax/convertors/html'
rdoc_dir = 'rdoc'
# This is rdoc1 but it doesn't work unless you DON'T wrap it in a task
# Generate html files from example ruby files
convertor = Syntax::Convertors::HTML.for_syntax "ruby"
replacement_key = "REPLACE_THIS_TEXT_WITH_PROPER_HTML"
# Create dummy files
Dir.glob('examples/*.rb').each do |file|
File.open("#{file}.txt", "w") do |dummy_file|
dummy_file.write(replacement_key)
end
end
# Call the rdoc task
Rake::RDocTask.new(:rdoc2) do |rdoc|
rdoc.rdoc_dir = rdoc_dir
rdoc.title = "pickled_optparse #{version}"
rdoc.rdoc_files.include('README*')
rdoc.rdoc_files.include('HISTORY*')
rdoc.rdoc_files.include('examples/*.txt')
rdoc.rdoc_files.include('lib/**/*.rb')
end
task :rdoc3 do
# Now use a hammer to replace the dummy text with the
# html we want to use in our ruby example code file.
html_header = File.read('rake_reqs/html_header.html')
Dir.glob('examples/*.rb').each do |file|
html_ruby = convertor.convert(File.read(file))
rdoc_file = "#{rdoc_dir}/examples/#{File.basename(file,".rb")}_rb_txt.html"
fixed_html = File.read(rdoc_file).gsub!(replacement_key, "#{html_header}#{html_ruby}")
File.open(rdoc_file, "w") {|f| f.write(fixed_html)}
File.delete("#{file}.txt")
end
end
task :rdoc => [:rdoc2, :rdoc3]
Sorry I can't give you an actual answer but I'm looking at sdoc myself.
You can install the gem from ruby gems.

Resources