cloudstack/scripts/vm/hypervisor/vmware/discover_networks.py
davidjumani d949302d0f
packaging: Adding Centos8, Ubuntu 20.04, XCPNG8.1 Support (#4068)
* DB : Add support for MySQL 8

- Splits commands to create user and grant access on database, the old
statement is no longer supported by MySQL 8.x
- `NO_AUTO_CREATE_USER` is no longer supported by MySQL 8.x so remove
that from db.properties conn parameters

For mysql-server 8.x setup the following changes were added/tested to
make it work with CloudStack in /etc/mysql/mysql.conf.d/mysqld.cnf and
then restart the mysql-server process:

    server_id = 1
    sql-mode="STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_ENGINE_SUBSTITUTION"
    innodb_rollback_on_timeout=1
    innodb_lock_wait_timeout=600
    max_connections=1000
    log-bin=mysql-bin
    binlog-format = 'ROW'

    default-authentication-plugin=mysql_native_password

Notice the last line above, this is to reset the old password based
authentication used by MySQL 5.x.

Developers can set empty password as follows:

    > sudo mysql -u root
    ALTER USER 'root'@'localhost' IDENTIFIED BY '';

In libvirt repository, there are two related commits

2019-08-23 13:13 Daniel P. Berrangé            ● rpm: don't enable socket activation in upgrade if --listen present
2019-08-22 14:52 Daniel P. Berrangé            ● remote: forbid the --listen arg when systemd socket activation

In libvirt.spec.in

        /bin/systemctl mask libvirtd.socket >/dev/null 2>&1 || :
        /bin/systemctl mask libvirtd-ro.socket >/dev/null 2>&1 || :
        /bin/systemctl mask libvirtd-admin.socket >/dev/null 2>&1 || :
        /bin/systemctl mask libvirtd-tls.socket >/dev/null 2>&1 || :
        /bin/systemctl mask libvirtd-tcp.socket >/dev/null 2>&1 || :

Co-authored-by: Wei Zhou <w.zhou@global.leaseweb.com>
Co-authored-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
Co-authored-by: Rohit Yadav <rohit.yadav@shapeblue.com>
2020-08-17 16:28:30 +05:30

288 lines
11 KiB
Python
Executable File

#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
from pyVim.connect import SmartConnect, SmartConnectNoSSL, Disconnect
from pyVmomi import vim
import atexit
import sys
import argparse
import json
isDebugLogs = False
hostClusterNameDict = {}
pgHostNameDict = {}
networksDict = {}
def log_message(msg):
if isDebugLogs == True:
print(msg)
def get_clusters(content, cluster=None):
if cluster is not None:
log_message("Getting clusters (name=" + cluster + ") ...")
else:
log_message("Getting clusters ...")
cluster_view = content.viewManager.CreateContainerView(content.rootFolder,
[vim.ClusterComputeResource],
True)
clusters = []
if cluster is not None:
for c in cluster_view.view:
if c.name == cluster:
clusters.append(c)
hosts = c.host
for host in hosts:
hostClusterNameDict[host.name] = c.name
break
else:
for c in cluster_view.view:
clusters.append(c)
hosts = c.host
for host in hosts:
hostClusterNameDict[host.name] = c.name
cluster_view.Destroy()
log_message('\t{} cluster(s) found'.format(len(clusters)))
for c in clusters:
log_message('\t' + c.name)
return clusters
def get_vm_hosts(clusters):
log_message("Getting ESX hosts ...")
hosts = []
for cluster in clusters:
hosts.extend(cluster.host)
log_message('\t{} host(s) found'.format(len(hosts)))
for host in hosts:
log_message('\t' + host.name)
return hosts
def get_vms(content):
log_message("Getting VMs ...")
vm_view = content.viewManager.CreateContainerView(content.rootFolder,
[vim.VirtualMachine],
True)
obj = [vm for vm in vm_view.view]
vm_view.Destroy()
return obj
def get_hosts_port_groups(hosts):
log_message("Collecting portGroups on hosts. This may take a while ...")
hostPgDict = {}
for host in hosts:
pgs = host.config.network.portgroup
hostPgDict[host] = pgs
for pg in pgs:
pgHostNameDict[pg.spec.name] = host.name
log_message("\tHost {} done.".format(host.name))
log_message("\tPortgroup collection complete.")
return hostPgDict
def get_vm_info(vm, hostPgDict):
vmPowerState = vm.runtime.powerState
log_message('\tVM: ' + vm.name + '(' + vmPowerState + ')')
get_vm_nics(vm, hostPgDict)
def get_vm_nics(vm, hostPgDict):
try:
for dev in vm.config.hardware.device:
if isinstance(dev, vim.vm.device.VirtualEthernetCard):
dev_backing = dev.backing
portGroup = None
vlanId = None
isolatedPvlan = None
isolatedPvlanType = None
vSwitch = None
if hasattr(dev_backing, 'port'):
portGroupKey = dev.backing.port.portgroupKey
dvsUuid = dev.backing.port.switchUuid
try:
dvs = content.dvSwitchManager.QueryDvsByUuid(dvsUuid)
except:
log_message('\tError: Unable retrieve details for distributed vSwitch ' + dvsUuid)
portGroup = ''
vlanId = ''
vSwitch = ''
else:
pgObj = dvs.LookupDvPortGroup(portGroupKey)
portGroup = pgObj.config.name
try:
if isinstance(pgObj.config.defaultPortConfig.vlan, vim.dvs.VmwareDistributedVirtualSwitch.PvlanSpec):
for pvlanConfig in dvs.config.pvlanConfig:
if pvlanConfig.secondaryVlanId == pgObj.config.defaultPortConfig.vlan.pvlanId:
vlanId = str(pvlanConfig.primaryVlanId)
isolatedPvlanType = pvlanConfig.pvlanType
isolatedPvlan = str(pgObj.config.defaultPortConfig.vlan.pvlanId)
break
else:
vlanId = str(pgObj.config.defaultPortConfig.vlan.vlanId)
except AttributeError:
log_message('\tError: Unable retrieve details for portgroup ' + portGroup)
vlanId = ''
vSwitch = str(dvs.name)
else:
portGroup = dev.backing.network.name
vmHost = vm.runtime.host
# global variable hostPgDict stores portGroups per host
pgs = hostPgDict[vmHost]
for p in pgs:
if portGroup in p.key:
vlanId = str(p.spec.vlanId)
vSwitch = str(p.spec.vswitchName)
if portGroup is None:
portGroup = ''
if vlanId is None:
vlanId = ''
vmHostName = None
vmClusterName = None
try:
vmHostName = vm.runtime.host.name
except AttributeError:
vmHostName = ''
try:
vmClusterName = vm.runtime.host.parent.name
except AttributeError:
vmClusterName = ''
add_network(portGroup, vlanId, isolatedPvlanType, isolatedPvlan, vSwitch, vm.name, dev.deviceInfo.label, dev.macAddress, vmClusterName, vmHostName)
log_message('\t\t' + dev.deviceInfo.label + '->' + dev.macAddress +
' @ ' + vSwitch + '->' + portGroup +
' (VLAN ' + vlanId + ')')
except AttributeError:
log_message('\tError: Unable retrieve details for ' + vm.name)
def add_network(portGroup, vlanId, isolatedPvlanType, isolatedPvlan, vSwitch, vmName, vmDeviceLabel, vmMacAddress, vmClusterName, vmHostName):
key = vSwitch + '->' + portGroup + ' (VLAN ' + vlanId + ')'
device = {"label": vmDeviceLabel, "macaddress": vmMacAddress}
vm = {"name":vmName, "device": device}
if key in networksDict:
network = networksDict[key]
network["virtualmachines"].append(vm)
networksDict[key] = network
else:
vms = [vm]
try:
host = pgHostNameDict[portGroup]
except KeyError:
host = vmHostName
try:
cluster = hostClusterNameDict[host]
except KeyError:
cluster = vmClusterName
network = {"portgroup": portGroup, "cluster": cluster, "host": host, "switch": vSwitch, "virtualmachines": vms}
if vlanId != '':
network["vlanid"] = vlanId
if isolatedPvlan is not None:
network["isolatedpvlan"] = isolatedPvlan
if isolatedPvlanType is not None:
network["isolatedpvlantype"] = isolatedPvlanType
networksDict[key] = network
def get_args():
parser = argparse.ArgumentParser(
description='Arguments for talking to vCenter')
parser.add_argument('-s', '--host',
required=True,
action='store',
help='vSpehre service to connect to')
parser.add_argument('-o', '--port',
type=int,
default=443,
action='store',
help='Port to connect on')
parser.add_argument('-u', '--user',
required=True,
action='store',
help='User name to use')
parser.add_argument('-p', '--password',
required=False,
action='store',
help='Password to use')
parser.add_argument('-c', '--cluster',
required=False,
action='store',
help='Cluster for which discover networks')
parser.add_argument('-S', '--disable_ssl_verification',
required=False,
action='store_true',
help='Disable ssl host certificate verification')
parser.add_argument('-d', '--debug',
required=False,
action='store_true',
help='Debug log messages')
args = parser.parse_args()
return args
def main():
global content, isDebugLogs, hostClusterNameDict, pgHostNameDict, networksDict
args = get_args()
if args.password:
password = args.password
else:
password = getpass.getpass(prompt='Enter password for host %s and '
'user %s: ' % (args.host, args.user))
if args.debug:
isDebugLogs = True
if args.disable_ssl_verification:
serviceInstance = SmartConnectNoSSL(host=args.host,
user=args.user,
pwd=password,
port=int(args.port))
else:
serviceInstance = SmartConnect(host=args.host,
user=args.user,
pwd=password,
port=int(args.port))
atexit.register(Disconnect, serviceInstance)
content = serviceInstance.RetrieveContent()
if args.cluster:
clusters = get_clusters(content, args.cluster)
else:
clusters = get_clusters(content)
hosts = []
if len(clusters) > 0:
hosts = get_vm_hosts(clusters)
if len(hosts) > 0:
hostPgDict = get_hosts_port_groups(hosts)
vms = get_vms(content)
log_message('\t{} VM(s) found'.format(len(vms)))
for vm in vms:
get_vm_info(vm, hostPgDict)
networks = list(networksDict.values())
response = {"count": len(networks), "networks": networks}
print(json.dumps(response, indent=2, sort_keys=True))
# Main section
if __name__ == "__main__":
sys.exit(main())