openstack-virtual-baremetal/openstack_virtual_baremetal/build_nodes_json.py

172 lines
5.8 KiB
Python
Executable File

#!/usr/bin/env python
# Copyright 2015 Red Hat Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import argparse
import json
import os
import sys
import yaml
from neutronclient.v2_0 import client as neutronclient
from novaclient import client as novaclient
def _parse_args():
parser = argparse.ArgumentParser(
prog='build-nodes-json.py',
description='Tool for collecting virtual IPMI details',
)
parser.add_argument('--env',
dest='env',
default=None,
help='YAML file containing OVB environment details')
parser.add_argument('--bmc_prefix',
dest='bmc_prefix',
default='bmc',
help='BMC name prefix')
parser.add_argument('--baremetal_prefix',
dest='baremetal_prefix',
default='baremetal',
help='Baremetal name prefix')
parser.add_argument('--private_net',
dest='private_net',
default='private',
help='DEPRECATED: This parameter is ignored.')
parser.add_argument('--provision_net',
dest='provision_net',
default='provision',
help='Provisioning network name')
parser.add_argument('--nodes_json',
dest='nodes_json',
default='nodes.json',
help='Destination to store the nodes json file to')
args = parser.parse_args()
return args
def _get_names(args):
if args.env is None:
bmc_base = args.bmc_prefix
baremetal_base = args.baremetal_prefix
provision_net = args.provision_net
else:
with open(args.env) as f:
e = yaml.safe_load(f)
bmc_base = e['parameters']['bmc_prefix']
baremetal_base = e['parameters']['baremetal_prefix']
provision_net = e['parameters']['provision_net']
return bmc_base, baremetal_base, provision_net
def _get_clients():
cloud = os.environ.get('OS_CLOUD')
if cloud:
import os_client_config
nova = os_client_config.make_client('compute', cloud=cloud)
neutron = os_client_config.make_client('network', cloud=cloud)
else:
username = os.environ.get('OS_USERNAME')
password = os.environ.get('OS_PASSWORD')
tenant = os.environ.get('OS_TENANT_NAME')
auth_url = os.environ.get('OS_AUTH_URL')
if not username or not password or not tenant or not auth_url:
print('Source an appropriate rc file first')
sys.exit(1)
nova = novaclient.Client(2, username, password, tenant, auth_url)
neutron = neutronclient.Client(
username=username,
password=password,
tenant_name=tenant,
auth_url=auth_url
)
return nova, neutron
def _get_ports(neutron, bmc_base, baremetal_base):
all_ports = sorted(neutron.list_ports()['ports'], key=lambda x: x['name'])
bmc_ports = list([p for p in all_ports
if p['name'].startswith(bmc_base)])
bm_ports = list([p for p in all_ports
if p['name'].startswith(baremetal_base)])
if len(bmc_ports) != len(bm_ports):
raise RuntimeError('Found different numbers of baremetal and '
'bmc ports.')
return bmc_ports, bm_ports
def _build_nodes(nova, bmc_ports, bm_ports, provision_net):
node_template = {
'pm_type': 'pxe_ipmitool',
'mac': '',
'cpu': '',
'memory': '',
'disk': '',
'arch': 'x86_64',
'pm_user': 'admin',
'pm_password': 'password',
'pm_addr': '',
'capabilities': 'boot_option:local',
}
nodes = []
bmc_bm_pairs = []
for bmc_port, baremetal_port in zip(bmc_ports, bm_ports):
baremetal = nova.servers.get(baremetal_port['device_id'])
node = dict(node_template)
node['pm_addr'] = bmc_port['fixed_ips'][0]['ip_address']
bmc_bm_pairs.append((node['pm_addr'], baremetal.name))
node['mac'] = [baremetal.addresses[provision_net][0]['OS-EXT-IPS-MAC:mac_addr']]
flavor = nova.flavors.get(baremetal.flavor['id'])
node['cpu'] = flavor.vcpus
node['memory'] = flavor.ram
node['disk'] = flavor.disk
nodes.append(node)
return nodes, bmc_bm_pairs
def _write_nodes(nodes, args):
with open(args.nodes_json, 'w') as node_file:
contents = json.dumps({'nodes': nodes}, indent=2)
node_file.write(contents)
print(contents)
# TODO(bnemec): parameterize this based on args.nodes_json
def _write_pairs(bmc_bm_pairs):
with open('bmc_bm_pairs', 'w') as pairs_file:
pairs_file.write('# A list of BMC addresses and the name of the '
'instance that BMC manages.\n')
for i in bmc_bm_pairs:
pair = '%s %s' % i
pairs_file.write(pair + '\n')
print(pair)
def main():
args = _parse_args()
bmc_base, baremetal_base, provision_net = _get_names(args)
nova, neutron = _get_clients()
bmc_ports, bm_ports = _get_ports(neutron, bmc_base, baremetal_base)
nodes, bmc_bm_pairs = _build_nodes(nova, bmc_ports, bm_ports, provision_net)
_write_nodes(nodes, args)
_write_pairs(bmc_bm_pairs)
if __name__ == '__main__':
main()