alnet
alnet

Reputation: 1243

Using parameters with YAML

I have the following YAML. I want to parse it and create objects accordingly. As you can see one argument of the application is ip of the host. Is it possible to use some kind of parameter and not write the ip's hard coded?

hosts:
-
  name: host_A
  ip: 1.1.1.1
  applications:
  -
    name: xyz
    args:
    - --connect_to=2.2.2.2

-
  name: host_B
  ip: 2.2.2.2
  applications:
  -
    name: xyz
    args:
    - --connect-to=1.1.1.1

As I understand using &ip / *ip is not possible as both hosts share this parameter.

So basically, i want to do something like:

hosts:
-
  name: host_A
  ip: 1.1.1.1
  applications:
  -
    name: xyz
    args:
    - --connect_to=&host_B.ip

-
  name: host_B
  ip: 2.2.2.2
  applications:
  -
    name: xyz
    args:
    - --connect-to=&host_A.ip

Upvotes: 0

Views: 2068

Answers (1)

peter
peter

Reputation: 42207

You can use parameters to create your Hash and YAML file (use of the array with ip in the example) and if you enumerate your Hash after the loading from YAML you can do the following. I took the liberty to use a Hash of Hashes instead of an array of Hashes, I'm sure you can adapt that is you don't have control over the YAML structure.

require 'yaml'

$hosts = {}
ip = ["1.1.1.1", "2.2.2.2", "3.3.3.3"]
$hosts['host_A'] = {"ip"=>"#{ip[0]}", "applications"=>[{"name"=>"xyz", "args"=>["--connect_to=host_B"]}]}
$hosts['host_B'] = {"ip"=>"#{ip[1]}", "applications"=>[{"name"=>"xyz", "args"=>["--connect_to=host_A"]}]}
$hosts['host_C'] = {"ip"=>"#{ip[2]}", "applications"=>[{"name"=>"xyz", "args"=>["--connect_to=host_B"]}]}
# Pass through YAML file
File.open('parameter.yaml', 'w') {|f| f.write $hosts.to_yaml }
$hosts = YAML.load_file('parameter.yaml')
p $hosts
#{"host_A"=>{"ip"=>"1.1.1.1", "applications"=>[{"name"=>"xyz", "args"=>["--connect_to=host_B"]}]}, "host_B"=>{"ip"=>"2.2.2.2", "applications"=>[{"name"=>"xyz", "args"=>["--connect_to=host_A"]}]}, "host_C"=>{"ip"=>"3.3.3.3", "applications"=>[{"name"=>"xyz", "args"=>["--connect_to=host_B"]}]}}


def ip host
  $hosts[host]['ip']
end

$hosts.each do |k, v|
  host = v['applications'].first['args'].first[/(host_.?)/]
  ip = ip(host)
  v['applications'].first['args'].first.gsub!(/(host_.?)/,ip)
end
p $hosts
# {"host_A"=>{"ip"=>"1.1.1.1", "applications"=>[{"name"=>"xyz", "args"=>["--connect_to=2.2.2.2"]}]}, "host_B"=>{"ip"=>"2.2.2.2", "applications"=>[{"name"=>"xyz", "args"=>["--connect_to=1.1.1.1"]}]}, "host_C"=>{"ip"=>"3.3.3.3", "applications"=>[{"name"=>"xyz", "args"=>["--connect_to=2.2.2.2"]}]}}

Upvotes: 0

Related Questions