summaryrefslogtreecommitdiffstats
path: root/validator/src/validation_tool/src/config.py
diff options
context:
space:
mode:
Diffstat (limited to 'validator/src/validation_tool/src/config.py')
-rw-r--r--validator/src/validation_tool/src/config.py176
1 files changed, 176 insertions, 0 deletions
diff --git a/validator/src/validation_tool/src/config.py b/validator/src/validation_tool/src/config.py
new file mode 100644
index 0000000..443467e
--- /dev/null
+++ b/validator/src/validation_tool/src/config.py
@@ -0,0 +1,176 @@
+##############################################################################
+# Copyright (c) 2015 Todd Gaunt and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import logging
+import sys
+import os
+import yaml
+import struct
+import socket
+
+from pharosvalidator import util
+from collections import namedtuple
+
+class Topology():
+ """
+ Topology: Class to store any number of Network classes
+ and metadata about them
+ """
+ def __init__(self, yaml_config):
+ # Dictionary of available networks
+ self.logger = logging.getLogger(__name__)
+ self.networks = {}
+ self.external_networks = []
+
+ # Fill the above dictionaries
+ self.parse_yaml(yaml_config)
+
+ def parse_yaml(self, yaml_config):
+ """
+ parse_yaml: parses the yaml configuration file this program uses
+ for all the network and node information
+ """
+ config = safe_yaml_read(yaml_config)
+ for network in config["networks"]:
+ self.logger.info("Reading network section {}".format(network))
+ if network == "admin":
+ self.networks[network] = Network(config["networks"][network])
+ #TODO
+ elif network == "external":
+ for external_network in config["networks"][network]:
+ self.external_networks.append(Network(external_network))
+
+class Network():
+ """
+ Network: Class to store all information on a given network
+ """
+ def __init__(self, network):
+ try:
+ self.logger = logging.getLogger(__name__)
+
+ # Some generic settings
+ self.enabled = network["enabled"]
+ self.vlan = network["vlan"]
+
+ # VM settings
+ self.installer_nic_type = network["installer_vm"]["nic_type"]
+ self.installer_members = network["installer_vm"]["members"]
+ self.installer_ip = network["installer_vm"]["ip"]
+
+ # Tuple containing the minimum and maximum
+ self.usable_ip_range = self.parse_ip_range(network["usable_ip_range"])
+ self.gateway = network["gateway"]
+ self.cidr = network["cidr"]
+ self.dhcp_range = network["dhcp_range"]
+ self.dns_domain = network["dns-domain"]
+ self.dns_search = network["dns-search"]
+
+ subnet, netmask = self.split_cidr(network["cidr"])
+ self.subnet = subnet
+ self.netmask = netmask
+
+ # List of all dns servers
+ self.dns_upstream = network["dns-upstream"]
+
+ self.nic_mapping = {}
+ except KeyError as e:
+ self.logger.error("Field {} not available in network configuration file".format(e))
+
+ def split_cidr(self, cidr):
+ """
+ split_cidr: Split up cidr notation subnets into a subnet string and a
+ netmask string
+
+ input: cidr notation of a subnet
+
+ output: Subnet string; Netmask string
+ """
+ split = cidr.split('/')
+ host_bits = int(split[1])
+ netmask = self.cidr_to_netmask(host_bits)
+ subnet = split[0]
+
+ return subnet, netmask
+
+ def parse_ip_range(self, ip_range_string):
+ """
+ parse_ip_range: Create a named tuple object that contains the lowest
+ ip address and the highest ip address from a configuration file
+
+ input: String formatted like so "min, max" where min/max are ip addresses
+
+ output: Named tuple object containing a minimum and maximum field
+ """
+ rp = ip_range_string.split(",")
+ ip_range = namedtuple("ip_range", ['minimum', 'maximum'])(minimum=min(rp), maximum=max(rp))
+ return ip_range
+
+ def cidr_to_netmask(self, cidr):
+ bits = 0xffffffff ^ (1 << 32 - cidr) - 1
+ netmask = socket.inet_ntoa(struct.pack('>I', bits))
+ self.logger.debug("Netmask generated from cidr '{}': '{}'".format(cidr, netmask))
+ return netmask
+
+class Inventory():
+ """
+ Inventory: Class to hold configuration file data
+ """
+ def __init__(self, yaml_config):
+ # Create the class logger
+ self.logger = logging.getLogger(__name__)
+
+ self.nodes = []
+
+ # Fill the above list
+ self.parse_yaml(yaml_config)
+
+ def parse_yaml(self, yaml_config):
+ config = safe_yaml_read(yaml_config)
+ nodes = []
+ for node in config["nodes"]:
+ self.nodes.append(Node(node))
+
+ def nodecount(self):
+ return len(self.nodes)
+
+class Node():
+ """
+ Node: Class to hold
+ """
+ def __init__(self, node):
+ self.logger = logging.getLogger(__name__)
+ try:
+ self.name = node["name"]
+ self.tags = node["tags"]
+ self.arch = node["arch"]
+ self.mac_address = node["mac_address"] # ipmi mac address
+ self.cpus = node["cpus"]
+ self.memory = node["memory"]
+ self.disk = node["disk"]
+ except KeyError as e:
+ self.logger.error("Field {} not available in inventory file".format(e))
+
+ # Power sub section
+ if node["power"]["type"] == "ipmi":
+ try:
+ self.ipmi_addr = node["power"]["address"]
+ self.ipmi_user = node["power"]["user"]
+ self.ipmi_pass = node["power"]["pass"]
+ except KeyError as e:
+ self.logger.error("Field {} not available in inventory file".format(e))
+ else:
+ pass
+
+def safe_yaml_read(yamlfile):
+ logger = logging.getLogger(__name__)
+ if os.path.isfile(yamlfile) == False:
+ logger.critical("Could not open find {}".format(yamlfile))
+ quit(1)
+ with open(yamlfile, 'r') as fd:
+ return yaml.load(fd.read())