ec2-aws create-volume & attach-volume script - ruby

I'm trying to make a ruby script to attach an EBS volume in AWS EC2. I'm missing some minor detail because I got an error at attaching the volume. Please see the error below:
#!/usr/bin/env ruby
require 'rubygems'
cmd = "ec2-create-volume --size 10 --region us-east-1 --availability-zone us-east-1a --type gp2"
system(cmd, :out => ['/tmp/volid', 'w'])
volid = `awk '{print $2}' /tmp/volid`
puts "#{volid}" -----> PUTS THE VARIABLE AS EXPECTED
cmd = "ec2-attach-volume #{volid} --instance i-2e69a1b5 --device /dev/xvdg"
system(cmd) ----> It shows ERROR -i instance/--instance is missing, somehow is putting the variable incorectly, it's like is not reading the command after the volid variable.
If I declare up voldid = 'vol-123' the script is working but if I put it from a file is not working even if output it shows vol-123.

At guess there is a end of line character at the end of the file you are reading the volume id from. The strip function removes leading and trailing whitespace which should clear this up.
It also seems like it would be easier to do
volid = File.read("/tmp/volid").strip
Rather than shelling out to awk. You can also avoid the use of a temporary file altogether by using one the various method that allow you to capture command output (backticks, popen, open3 etc). The aws ruby sdk is also pretty easy to use, although that is obviously a different kettle of fish.

Related

Ruby command download multiple folder from S3 use AWS CLI

I'm working on backup some accounts from my bucket with the prefix is id
When I exec once id is working correctly but when I used for multiple ids it will quit my ruby command. I was check, the error is when it run exec command. I was trying to research why it breaks but it takes more time. Anybody can help me why?
test.txt with 1 id:
1
test.txt with multiple ids:
1,2,3
My code:
file_names = ["test.txt"]
Dir.mkdir("logs") unless Dir.exist?("logs")
Dir.mkdir("data") unless Dir.exist?("data")
file_names.each do |file|
out_file = File.new("logs/#{file}", "w")
out_file.puts("Start read file #{file}")
member_ids = File.read("#{file}").strip!.split(",")
member_ids.each do |id|
Dir.mkdir("data/#{id}") unless Dir.exist?("data/#{id}")
command = "aws s3 sync s3://mybucket/#{id}/ data/#{id}/"
exec command
out_file.puts("#{id}")
end
out_file.puts("Finished read file #{file}")
out_file.close
end
This error by use exec command, change it to system command it will working :D

Terraform GCP Instance Metadata Startup Script Issue

I've been working with Terraform, v0.15.4, for a few weeks now, and have gotten to grips with most of the lingo. I'm currently trying to create a cluster of RHEL 7 instances dynamically on GCP, and have, for the most part, got it to run okay.
I'm at the point of deploying an instance with certain metadata passed along to it for use in scripts built into the machine image for configuration thereafter. This metadata is typically just passed via an echo into a text file, which the scripts then pickup as required.
It's... very simple. Echo "STUFF" > file... Alas, I am hitting the same issue OVER AND OVER and it's driving me INSANE. I've Google'd around for ages, but all I can find is examples of the exact thing that I'm doing, the only difference is that theirs works, mine doesn't... So hopefully I can get some help here.
My 'makes it half-way' code is as follows:
resource "google_compute_instance" "GP_Master_Node" {
...
metadata_startup_script = <<-EOF
echo "hello
you" > /test.txt
echo "help
me" > /test2.txt
EOF
Now the instance with this does create successfully, although when I look onto the instance, I get one file called ' /test.txt? ' (or if I 'ls' the file, it shows as ' /test.txt^M ') and no second file.. I can run any command instead of echo, and whilst the first finishes, the second+ does not. Why?? What on earth is causing that??
The following code I found also, but it doesn't work for me at all, with the error, 'Blocks of type "metadata" are not expected here.'
resource "google_compute_instance" "GP_Master_Node" {
...
metadata {
startup-script = "echo test > /test.txt"
}
Okaaaaay! Simple answer for a, in hindsight, silly question (sort of). The file was somehow formmated in DOS, meaning the script required a line continuation character to run correctly (specifically \ at the end of each individual command). Code as follows:
resource "google_compute_instance" "GP_Master_Node" {
...
metadata_startup_script = <<-EOF
echo "hello
you" > /test.txt \
echo "help
me" > /test2.txt \
echo "example1" > /test3.txt \
echo "and so on..." > /final.txt
EOF
However, what also fixed my issue was just 'refreshing' the file (probably a word for this, I don't know). I created a brand new file using touch, 'more'd the original file contents to screen, and then copy pasted them into the new one. On save, it is no longer DOS, as expected, and then when I run terraform the code runs as expected without requiring the line continuation characters at the end of commands.
Thank you to commentors for the help :)

How to assign file content to chef node attribute

I have fingreprint.txt at the location "#{node['abc.d']}/fingreprint.txt"
The contents of the file are as below:
time="2015-03-25T17:53:12C" level=info msg="SHA1 Fingerprint=7F:D0:19:C5:80:42:66"
Now I want to retrieve the value of fingerprint and assign it to chef attribute
I am using the following ruby block
ruby_block "retrieve_fingerprint" do
block do
path="#{node['abc.d']}/fingreprint.txt"
Chef::Resource::RubyBlock.send(:include, Chef::Mixin::ShellOut)
command = 'grep -Po '(?<=Fingerprint=)[^"]*' path '
command_out = shell_out(command)
node.default['fingerprint'] = command_out.stdout
end
action :create
end
It seems not to be working because of missing escape chars in command = 'grep -Po '(?<=Fingerprint=)[^"]*' path '.
Please let me know if there is some other way of assigning file content to node attribute
Two ways to answer this: first I would do the read (IO.read) and parsing (RegExp.new and friends) in Ruby rather than shelling out to grep.
if IO.read("#{node['abc.d']}/fingreprint.txt") =~ /Fingerprint=([^"]+)/
node.default['fingerprint'] = $1
end
Second, don't do this at all because it probably won't behave how you expect. You would have to take in to account both the two-pass loading process and the fact that default attributes are reset on every run. If you're trying to make an Ohai plugin, do that instead. If you're trying to use this data in later resources, you'll probably want to store it in a global variable and make copious use of the lazy {} helper.

How can I pass arguments to msfconsole -r resource.rc <arg1> <arg2>

So everything is in the title.
Is there a way I can pass arguments to :
msf> resource path/to/resource.rc <arg1> <arg2>
Or
msfconsole -r resource.rc <arg1> <arg2>
Those arguments would passed into the ruby resource code as follow:
<ruby>
ip = ARGV[1]
port = ARGV[2]
...
...
</ruby>
Unfortunately resource files don't accept arguments, but they do accept ruby blocks. So you can do it with a bit of trickery. Make a resource file that looks something like this:
Where it's using the ruby ENV command to pull in the environmental variable "DSTIP"
metasploit-framework [git:master]$ cat /tmp/test.rc
<ruby>
run_single("set RHOST #{ENV['DSTIP']}")
</ruby>
Now when I run msfconsole, I can set that DSTIP variable and it will set the RHOST when I start up MSF to whatever was in that environmental variable:
metasploit-framework [git:master]$ DSTIP=192.168.1.1 ./msfconsole -r /tmp/test.rc -Lq
[*] Processing /tmp/test.rc for ERB directives.
[*] resource (/tmp/test.rc)> Ruby Code (40 bytes)
RHOST => 192.168.1.1
You can do this with as many environmental variables as you want. Now if you want to run it from within MSFCONSOLE I tried changing the environmental variable after msfconsole was running with no luck. I'm sure there is a way that a beardy linux master will have to do it but I don't I'm sorry.
Side note: you can also use ruby file reads to pull in text from. (Think configuration file)
Hope this help!
mubix

How to pass command line parameters to capistrano

I am using Capistrano v2.9.0.
I run this command:
cap deploy:tryout -S testvar=thing
and my deploy.rb contains this:
namespace :deploy do
task :tryout do
if defined? testvar
puts "param: #{testvar}\n"
else
puts "no branch!\n"
end
end
end
The output is "no branch!". How do I pass values from the command line? I tried looking into the code, and I can see options.rb where it adds the passed parameter to options[:pre_vars], but that seems to be an instance variable, and I can't figure out how to access it from my deploy script.
Solution:
The options can be accessed via #parent.variables hash, so if the command line string is testvar=thing, then #parent.variables[:testvar] has the value string.
This seems really ugly and hacky, but it works.
Edit:
Turns out it is also available locally via variables[:testvar]

Resources