Replacing variable value in ruby while setting the value using "set" command - ruby

I have a .properties files as below:
user:abcd
pwd:xyz
system:test
Next, I have a ruby script with Watir for browser automation. In this script, I have statements like
browser.text_field(:id => 'identifierId').set "#{user}:variable to be replaced by its value from .properties file".
Similarly, other values need to be replaced for "pwd" and "system".
I tried the solution per below posts:
Replace properties in one file from those in another in Ruby
However, "set" command is setting whatever has been paased as arguments to it instead of replacing the variable with its value.
Please help.

You have to read the information out of the file.
Most Watir users leverage yaml files for this.
config/properties.yml:
user: abcd
pwd: xyz
system: test
Then read the yaml file & parse your data:
properties = YAML.safe_load(IO.read('config/properties.yml'))
text_field = browser.text_field(id: 'identifierId')
text_field.set properties['user']
Alternately you can take a look at Cheezy's Fig Newton gem, which is designed to work with his Page Object gem

Related

How i can Insert contents of text file with heredoc and variable with ruby

There was a problem when im creating the CLI. I'm want to give the user the opportunity to insert their data into a text file, for this I created a file and added a heredoc to it
I'm trying to get data from a text document that has a heredoc inside of it with a function that is supposed to interpolate
When I try to display the result of the file, I get the entire contents of the file, including the heredoc
an example will be below
I tried to solve my problem through File class
variable_name = File::open("path_directory/file_with_heredoc.txt", "r+")::read
Next, I decided to give the value of the variable to the terminal via
exec("echo #{variable_name}")
The terminal displays
file = <<-EOM
single text with def result: #{upcase_def("Hello")}
EOM
Tried to give through struct, but result is unchanged
exec("echo #{variable_name.strip}")
What do I need to do to get only data, no HEREDOC syntax?
I want to get this result
"single text with def result: HELLO"
I think this is what you are trying to do but I recommend you to first do some research why 'eval() is evil'. If the file is a user (or hacker) input you definitely want some sanitization there or a completely different approach.
def upcase_def(str)
str.upcase
end
data = File.read('file_with_heredoc.txt')
eval(data)
# => " single text with def result: HELLO\n"

Fetch variable from yaml in puppet manifest

I'm doing one project for puppet, however currently stuck in one logic.
Thus, want to know can we fetch variable from .yaml, .json or plain text file in puppet manifest file.
For example,
My puppet manifest want to create user but the variable exist in the .yaml or any configuration file, hence need to fetch the varibale from the outside file. The puppet manifest also can do looping if it exist multiple users in .yaml file.
I read about hiera but let say we are not using hiera is there any possible way.
There are a number of ways you can do this using a combination of built-in and stdlib functions, at least for YAML and JSON.
Using the built-in file function and the parseyaml or parsejson stdlib functions:
Create a file at mymodule/files/myfile.yaml:
▶ cat files/myfile.yaml
---
foo: bar
Then in your manifests read it into a string and parse it:
$myhash = parseyaml(file('mymodule/myfile.yaml'))
notice($myhash)
That will output:
Notice: Scope(Class[mymodule]): {foo => bar}
Or, using the loadyaml or loadjson stdlib functions:
$myhash = loadyaml('/etc/puppet/data/myfile.yaml')
notice($myhash)
The problem with that approach is that you need to know the path to file on the Puppet master. Or, you could use a Puppet 6 deferred function and read the data from a file on the agent node.
(Whether or not you should do this is another matter entirely - hint: answer is you almost certainly should be using Hiera - but that isn't the question you asked.)

Read files in Chef without writing to the node

I am trying to read a file's contents and use it in my ruby code. In this step, I am not trying to do anything on the bootstrapped node. All I want to do is read a JSON file that will reside in cookbook's files folder and read the contents of the file and do something. I just want to use the value coming from JSON in my code itself. The code example is shown below. Any help is appreciated.
Attributes: default.rb
default["xyz"]["ohs_servers"]=[
{"hostname"=> "intf301.linux.xyz.com","name" => "INTFIN_OHS_001", "short_name" => "OGS", "port" => "9931"},
{"hostname"=> "intf302.linux.xyz.com","name" => "INTFIN_OHS_001", "short_name" => "OHS", "port" => "9931"}
]
Machines: machines.rb
require 'rubygems'
require 'json'
require 'pp'
json = File.read('environment.json')
obj = JSON.parse(json)
number = obj["name"]
x = node["xyz"]["ohs_servers"][number]["hostname"]
JSON file in cookbook's files folder: environment.json
{
"template_name": "environment_template",
"number": 0
}
Even if I don't really get why you don't want to use attributes for this:
What you want is to ensure the cookbook files are in the cache even if there's no resource calling them, the way to go is to configure the client.rb on the node with the no_lazy_load attribute to true
Quoting the documentation about this option:
no_lazy_load Use to download all cookbook files and templates at the
beginning of the chef-client run. Default value: true.
I'm unsure if the default value has changed with 12 or on wich version, but I'm quite sure it was false in chef 11 (loading file or template when the provider referencing them is called)
Then you can read your file using
File::read("#{Chef::Config['file_cache_path']}/cookbooks/my_cookbook/files/my_file.json")
Edit: Just saw the comment of Stephen King, I more or less paraphrased Seth Vargo's answer here :/
use cookbook_file and then add run_action(:create)
cookbook_file "myfile.txt" do
path "somepathyouwantthefilebe/myfile.txt"
source "myfile.txt" #the name of the file in files folder of your cookbook"
end.run_action(:create) # read notes** bellow
then you can have some ruby code to read from it
for example
File::read("somepathyouwantthefilebe/myfile.txt")
** the run action is nessecary since you are combining ruby code and resources in chef-zero

How to write a file that is both valid ruby syntax and valid YAML syntax

In order to have only a single point of configuration for my app I need to make a YAML config file that is also valid ruby code. I.e. a mixed syntax file that can be parsed as YAML and parsed as ruby.
My application is a suite of processes managed by the god gem. I want to load a new group of maintained processes (watches) for each new configuration file.
God allows loading a new app.god (ruby) file with new watches defined, but I don't want an app.god and app.yml, just one file. Simplest might be to just have the app.god file and include the configuration within that, but I preferred the idea of a yml file that was also valid ruby code.
#I found this that might be helpful:
#This is a valid ruby and a valid YAML file
#Comments are the same in YAML and ruby
true ?true:
- <<YAML.to_i
# At this point in ruby it is the contents of a here doc (that will be
# converted to an integer and negated if true happens not to be true)
# In YAML it is a hash with the first entry having key "true ?true"
# representing a list containing the string "- <<YAML.to_i"
# If your YAML object should be a list not a hash you could remove the first line
any_valid_yaml: from here
a_list:
- or
- anything
- really
#Then mark the end of the YAML document with
---
#And YAML is done and ignores anything from here on
#Next terminate the ruby here document
YAML
#Now we're in ruby world
#this = "pure ruby"
def anything(ruby)
"here"
end

Replace properties in one file from those in another in Ruby

I want to replace properties in one file from those in another. (I am new to ruby, and read about Ruby and YAML. I have a Java background)
Eg.
File 1
server_ip_address=$[ip]
value_threshold=$[threshold]
system_name=$[sys_name]
File 2
ip=192.168.1.1
threshold=10
sys_name=foo
The ruby script should replace the $ values by their real values (I do not know if $[] is the format used in ruby. Also do Files 1 and 2 have to be YAML files, or erb files?) and produce File 1 as :
server_ip_address=192.168.1.1
value_threshold=10
system_name=foo
I searched the web for this, but could not express it in the right keywords to find a solution/pointer to a solution/reference material on google. How can this be done by a ruby script?
Thanks
If you can switch the formats, this should be as easy as:
require 'yaml'
variables = YAML.load(File.open('file2.yaml'))
template = File.read('file1.conf')
puts template.gsub(/\$\[(\w+)\]/) { variables[$1] }
Your template can stay as-is, but the substitution file would look like:
ip: 192.168.1.1
threshold: 10
sys_name: foo
This makes it easy to read in using the YAML library.

Resources