172 lines
5.8 KiB
Python
Executable File
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()
|