python key unknown in yaml - python

I have the following yaml file
name: somehost
values:
network_lo: "127.0.0.1"
network_eth0: "10.10.10.10"
hardwaremodel: x64
network_eth1: "192.168.10.10"
I would like to fetch all network* keys / values and print there values in an single value.
Though the interfaces could have different names. So i don't know what the interface name is called.
Normally I would do something like this:
with open(file, 'r') as stream:
facts = yaml.load(stream)
multiple = facts['values']['network*']
# single interface
print facts['values']['network_db_backend']
expected
# all interfaces
print multiple
expected: 127.0.0.1, 10.10.10.10, 192.168.10.10
How can I go over an yaml file fetch all network interfaces and print there values into a single string ?

something like this should work
import yaml
with open('file.yaml''', 'r') as stream:
facts = yaml.load(stream)
multiple = ', '.join([val for (key,val) in facts['values'].iteritems() if "network" in key])
# single interface
print facts['values']['network_lo']
# 127.0.0.1
# all interfaces
print multiple
and you can replace
"network" in key
with a regexp if you wish

Related

Python - Get empty key from yml file

I have a lot yaml file names that have similar structure but with different data. I need to parse out selective data, and put into a single csv (excel) file as three columns.
But i facing an issue with empty key, that always gives me an "KeyError: 'port'"
my yaml file example:
base:
server: 10.100.80.47
port: 3306
namePrefix: well
user: user1
password: kjj&%$
base:
server: 10.100.80.48
port:
namePrefix: done
user: user2
password: fhfh#$%
In the second block i have an empty "port", and my script is stuck on that point.
I need that always that an empty key is found it doesn't write anything.
from asyncio.windows_events import NULL
from queue import Empty
import yaml
import csv
import glob
yaml_file_names = glob.glob('./*.yaml')
rows_to_write = []
for i, each_yaml_file in enumerate(yaml_file_names):
print("Processing file {} of {} file name: {}".format(
i+1, len(yaml_file_names),each_yaml_file))
with open(each_yaml_file) as file:
data = yaml.safe_load(file)
for v in data:
if "port" in v == "":
data['base']['port'] = ""
rows_to_write.append([data['base']['server'],data['base']['port'],data['server']['host'],data['server']['contex']])
with open('output_csv_file.csv', 'w', newline='') as out:
csv_writer = csv.writer(out)
csv_writer.writerow(["server","port","hostname", "contextPath"])
csv_writer.writerows(rows_to_write)
print("Output file output_csv_file.csv created")
You are trying to access the key by index e.g.
data['base']['port']
But what you want is to access it with the get method like so:
data['base'].get('port')
This way if the key does not exists it return None as default, and you could even change the default value to whatever you want by passing it as the second parameter.
In PyYAML, an empty element is returned as None, not an empty string.
if data['base']['port'] is None:
data['base']['port'] = ""
Your yaml file is invalid. In yaml file, whenever you have a key (like port: in your example) you must provide a value, you cannot leave it empty and go to the next line. Unless the value is the next bunch of keys of course, but in that case you need to ident the following lines one step more, which is obviously not what you intend to do here.
This is likely why you cannot parse the file as expected with the python yaml module. If you are the creator of those yaml file, you really need to put a key in the file like port: None if you don't want to provide a value for the port, or even better you just not provide any port key at all.
If they are provided to you by someone else, ask them to provide valid yaml files.
Then the other solutions posted should work.

I want to be able to pull login info from a CSV to use as parameters for the redfish object [duplicate]

This question already has answers here:
How do I read and write CSV files with Python?
(7 answers)
Closed 4 years ago.
if __name__ == "__main__":
# When running on the server locally use the following commented values
# iLO_https_url = "blobstore://."
# iLO_account = "None"
# iLO_password = "None"
# When running remotely connect using the iLO secured (https://) address,
# iLO account name, and password to send https requests
# iLO_https_url acceptable examples:
# "https://10.0.0.100"
# "https://f250asha.americas.hpqcorp.net"
iLO_https_url = "https://10.0.0.100"
iLO_account = "admin"
iLO_password = "password"
# Create a REDFISH object
try:
REDFISH_OBJ = RedfishObject(iLO_https_url, iLO_account, iLO_password)
except ServerDownOrUnreachableError as excp:
sys.stderr.write("ERROR: server not reachable or doesn't support " \
"RedFish.\n")
sys.exit()
except Exception as excp:
raise excp
ex4_reset_server(REDFISH_OBJ)
REDFISH_OBJ.redfish_client.logout()
Above is the "login" part of the script im writing. In this part, REDFISH_OBJ = RedfishObject(iLO_https_url, iLO_account, iLO_password), I would like to replace iLO_https_url with a variable whose value would be pulled from a simple CSV file. The CSV would have 3 columns...ip, username,pwd.
I'm trying to execute the other part of the script, not shown here, on every IP in the CSV file. I need to do this in python.
The easiest way is to use the open() function with the split() function.
Try something like this:
with open("data.csv", encoding="utf-8") as csv_file:
iLO_account, iLO_password, iLO_https_url = csv_file.readline().split(",")
If you are separating your entries with new line breaks, simply replace the ",", with a "\n"

How to call and iterate values from a yaml file parsed using python?

I have a yaml file as below:
server1:
host: os1
ip: ##.###.#.##
path: /var/log/syslog
file: syslog
identityfile: /identityfile/keypair.pub
server2:
host: os2
ip: ##.###.#.##
path: /var/log/syslog
file: syslog.1
identityfile: /identityfile/id_rsa.pub
I have a piece of code to parse the yaml and read entries.
read data from the config yaml file
def read_yaml(file):
with open(file, "r") as stream:
try:
config = yaml.load(stream)
print(config)
except yaml.YAMLError as exc:
print(exc)
print("\n")
return config
read_yaml("config_file")
print(config)
My problems:
1. I am unable to return values and I get a "NameError: name 'config' is not defined" at the print statement called outside the function.
How can I iterate and read the values in my yaml file by passing only the parameters?
Ex:
print('{host}#{ip}:{path}'.format(**config['os1']))
but without the 'os1' as the yaml file may have 100s of entries
I ensured there are no duplicates by using sets but want to use a loop and store the values from my string formatting command into a variable without using 'os1' or 'os2' or 'os#'.
def iterate_yaml():
remotesys = set()
for key,val in config.items():
print("{} = {}".format(key,val))
#check to ensure duplicates are removed by storing it in a set
remotesys.add('{host}#{ip}:{path}'.format(**config['os1']))
remotesys.add('{host}#{ip}:{path}'.format(**config['os2']))
remotesys.add('{host}#{ip}:{path}'.format(**config['os3']))
Thanks for the help.
You get the NameError exception because you don't return any values. You have to return config from the function.
For example:
def read_yaml(...):
# code
return config
Then, by calling read_yaml, you'll get your configuration returned.
Check the Python documentation & tutorials for that.
2-3. You can perform a for loop using the dict.items method.
For example:
x = {'lol': 1, 'kek': 2}
for name, value in x.items():
print(name, value)

get key basis on value by reading property file in python?

I have a property file "holder.txt" like this which is in key=value format. Here key is clientId and value is hostname.
p10=machineA.abc.host.com
p11=machineB.pqr.host.com
p12=machineC.abc.host.com
p13=machineD.abc.host.com
Now I want to read this file in python and get corresponding clientId where this python script is running. For example: if python script is running on machineA.abc.host.com then it should give me p10 as clientId. Similarly for others.
import socket, ConfigParser
hostname=socket.getfqdn()
print(hostname)
# now basis on "hostname" figure out whats the clientId
# by reading "holder.txt" file
Now I have worked with ConfigParser but my confusion is how can I get value of key which is clientId basis on what hostname it is? Can we do this in python?
You Need to read and store the holder file in memory as a dictionary:
mappings = {}
with open('holder.txt', 'r') as f:
for line in f:
mapping = line.split('=')
mappings[mapping[1].rstrip()] = mapping[0]
Then perform a mapping every time you want to get clientId from hostname:
import socket, ConfigParser
hostname=socket.getfqdn()
clientId = mappings[hostname]
Hope that helps.

Using nslookup to find domain name and only the domain name

Currently I have a text file with mutiple IP's I am currently attempting to pull only the domain name from the set of information given using nslookup (code below)
with open('test.txt','r') as f:
for line in f:
print os.system('nslookup' + " " + line)
This works in so far that it pulls all the information from the first IP's. I can't get it passed the first IP but I'm currently attempting to clean up the information recived to only the Domain name of the IP. Is there any way to do that or do I need to use a diffrent module
Like IgorN, I wouldn't make a system call to use nslookup; I would also use socket. However, the answer shared by IgorN provides the hostname. The requestor asked for the domain name. See below:
import socket
with open('test.txt', 'r') as f:
for ip in f:
fqdn = socket.gethostbyaddr(ip) # Generates a tuple in the form of: ('server.example.com', [], ['127.0.0.1'])
domain = '.'.join(fqdn[0].split('.')[1:])
print(domain)
Assuming that test.txt contains the following line, which resolves to a FQDN of server.example.com:
127.0.0.1
this will generate the following output:
example.com
which is what (I believe) the OP desires.
import socket
name = socket.gethostbyaddr(‘127.0.0.1’)
print(name) #to get the triple
print(name[0]) #to just get the hostname

Categories