mirror of
https://github.com/vmware/vsphere-automation-sdk-python.git
synced 2024-11-21 17:29:59 -05:00
Updated the latest bindings and samples for 70U3 release (#288)
Signed-off-by: shweta <spurohit@vmware.com>
This commit is contained in:
parent
4fb7d4878f
commit
73624d9e20
@ -1 +1 @@
|
||||
<a href='vapi_client_bindings-3.6.0-py2.py3-none-any.whl'>vapi_client_bindings-3.6.0-py2.py3-none-any.whl</a><br />
|
||||
<a href='vapi_client_bindings-3.7.0-py2.py3-none-any.whl'>vapi_client_bindings-3.7.0-py2.py3-none-any.whl</a><br />
|
Binary file not shown.
Binary file not shown.
@ -1 +1 @@
|
||||
<a href='vapi_common_client-2.25.0-py2.py3-none-any.whl'>vapi_common_client-2.25.0-py2.py3-none-any.whl</a><br />
|
||||
<a href='vapi_common_client-2.30.0-py2.py3-none-any.whl'>vapi_common_client-2.30.0-py2.py3-none-any.whl</a><br />
|
Binary file not shown.
@ -1 +1 @@
|
||||
<a href='vapi_runtime-2.25.0-py2.py3-none-any.whl'>vapi_runtime-2.25.0-py2.py3-none-any.whl</a><br />
|
||||
<a href='vapi_runtime-2.30.0-py2.py3-none-any.whl'>vapi_runtime-2.30.0-py2.py3-none-any.whl</a><br />
|
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
lxml >= 4.3.0
|
||||
pyVmomi >= 6.7
|
||||
vapi-client-bindings == 3.6.0
|
||||
vapi-client-bindings == 3.7.0
|
||||
vmc-client-bindings
|
||||
nsx-python-sdk
|
||||
nsx-policy-python-sdk
|
||||
|
@ -131,7 +131,7 @@ class LibraryPublishSubscribe(SampleBase):
|
||||
assert not sub_item.cached, 'Subscribed item must not be cached'
|
||||
|
||||
# Force synchronize the subscribed library item to fetch and cache the content
|
||||
self.client.subscribed_item_service.sync(sub_item_id, True)
|
||||
self.client.subscribed_item_service.sync(sub_item_id, True, False)
|
||||
# It is not mandatory to verify sync, it is just for demonstrating the sample workflow.
|
||||
assert (ClsSyncHelper(self.client, self.SYNC_TIMEOUT_SEC).
|
||||
verify_item_sync(sub_item_id))
|
||||
|
193
samples/vsphere/vcenter/guest/cloudinitDataCustomizationSpecs.py
Normal file
193
samples/vsphere/vcenter/guest/cloudinitDataCustomizationSpecs.py
Normal file
@ -0,0 +1,193 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
* *******************************************************
|
||||
* Copyright (c) VMware, Inc. 2021. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
* *******************************************************
|
||||
*
|
||||
* DISCLAIMER. THIS PROGRAM IS PROVIDED TO YOU "AS IS" WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, WHETHER ORAL OR WRITTEN,
|
||||
* EXPRESS OR IMPLIED. THE AUTHOR SPECIFICALLY DISCLAIMS ANY IMPLIED
|
||||
* WARRANTIES OR CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY,
|
||||
* NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
"""
|
||||
|
||||
__author__ = 'VMware, Inc.'
|
||||
__copyright__ = 'Copyright 2021 VMware, Inc. All rights reserved.'
|
||||
__vcenter_version__ = 'VCenter 7.0 U3'
|
||||
|
||||
from com.vmware.vcenter.guest_client import CustomizationSpec,\
|
||||
CloudConfiguration, CloudinitConfiguration, ConfigurationSpec,\
|
||||
GlobalDNSSettings
|
||||
from pprint import pprint
|
||||
from samples.vsphere.common import sample_cli, sample_util
|
||||
from samples.vsphere.common.ssl_helper import get_unverified_session
|
||||
from vmware.vapi.vsphere.client import create_vsphere_client
|
||||
import os
|
||||
|
||||
|
||||
class CloudinitDataCustomizationSpecs(object):
|
||||
"""
|
||||
Demonstrates create/list/get/set/delete cloud-init data customizationSpecs
|
||||
Sample Prerequisites: 1 vcenter, no ESXi nor VM needed
|
||||
"""
|
||||
def __init__(self):
|
||||
self.metadata = None
|
||||
self.userdata = None
|
||||
self.parser = sample_cli.build_arg_parser()
|
||||
self.args = sample_util.process_cli_args(self.parser.parse_args())
|
||||
self.session =\
|
||||
get_unverified_session() if self.args.skipverification else None
|
||||
self.client = create_vsphere_client(server=self.args.server,
|
||||
username=self.args.username,
|
||||
password=self.args.password,
|
||||
session=self.session)
|
||||
self.specs_svc = self.client.vcenter.guest.CustomizationSpecs
|
||||
|
||||
def createCloudinitDataSpec(self, specName, specDesc):
|
||||
"""
|
||||
create a cloud-init data customizationSpec
|
||||
"""
|
||||
print('------create 1 linux cloud-init data CustomizationSpec-------')
|
||||
cloudinitConfig = CloudinitConfiguration(metadata=self.metadata,
|
||||
userdata=self.userdata)
|
||||
cloudConfig =\
|
||||
CloudConfiguration(cloudinit=cloudinitConfig,
|
||||
type=CloudConfiguration.Type('CLOUDINIT'))
|
||||
configSpec = ConfigurationSpec(cloud_config=cloudConfig)
|
||||
globalDnsSettings = GlobalDNSSettings()
|
||||
adapterMappingList = []
|
||||
customizationSpec =\
|
||||
CustomizationSpec(configuration_spec=configSpec,
|
||||
global_dns_settings=globalDnsSettings,
|
||||
interfaces=adapterMappingList)
|
||||
createSpec = self.specs_svc.CreateSpec(name=specName,
|
||||
description=specDesc,
|
||||
spec=customizationSpec)
|
||||
self.specs_svc.create(spec=createSpec)
|
||||
print('{} has been created'.format(specName))
|
||||
print('-------------------------------------------------------------')
|
||||
|
||||
def createSpecWithMetadataInYamlAndUserdata(self):
|
||||
"""
|
||||
create a linux cloud-init data customizationSpec with metadata in yaml
|
||||
format and userdata
|
||||
"""
|
||||
metadataYamlFilePath = os.path.join(os.path.dirname(
|
||||
os.path.realpath(__file__)),
|
||||
'sample_metadata.yaml')
|
||||
userdataFilePath = os.path.join(os.path.dirname(
|
||||
os.path.realpath(__file__)),
|
||||
'sample_userdata')
|
||||
with open(metadataYamlFilePath, "r") as fp:
|
||||
self.metadata = fp.read().rstrip('\n')
|
||||
with open(userdataFilePath, "r") as fp:
|
||||
self.userdata = fp.read().rstrip('\n')
|
||||
self.createCloudinitDataSpec('specWithMetadataInYamlAndUserdata',
|
||||
'linux cloud-init data customization spec'
|
||||
'with metadata in yaml format and '
|
||||
'userdata')
|
||||
|
||||
def createSpecWithMetadataInJsonAndUserdata(self):
|
||||
"""
|
||||
create a linux cloud-init data customizationSpec with metadata in json
|
||||
format and userdata
|
||||
"""
|
||||
metadataYamlFilePath = os.path.join(os.path.dirname(
|
||||
os.path.realpath(__file__)),
|
||||
'sample_metadata.json')
|
||||
userdataFilePath = os.path.join(os.path.dirname(
|
||||
os.path.realpath(__file__)),
|
||||
'sample_userdata')
|
||||
with open(metadataYamlFilePath, "r") as fp:
|
||||
self.metadata = fp.read().rstrip('\n')
|
||||
with open(userdataFilePath, "r") as fp:
|
||||
self.userdata = fp.read().rstrip('\n')
|
||||
self.createCloudinitDataSpec('specWithMetadataInJsonAndUserdata',
|
||||
'linux cloud-init data customization spec'
|
||||
'with metadata in json format and '
|
||||
'userdata')
|
||||
|
||||
def createSpecWithMetadataOnly(self):
|
||||
"""
|
||||
create a linux cloud-init data customizationSpec with metadata in yaml
|
||||
format and without userdata
|
||||
"""
|
||||
metadataYamlFilePath = os.path.join(os.path.dirname(
|
||||
os.path.realpath(__file__)),
|
||||
'sample_metadata.yaml')
|
||||
with open(metadataYamlFilePath, "r") as fp:
|
||||
self.metadata = fp.read().rstrip('\n')
|
||||
self.createCloudinitDataSpec('specWithMetadataOnly',
|
||||
'linux cloud-init data customization spec'
|
||||
'with metadata only')
|
||||
|
||||
def listCustomizationSpecs(self):
|
||||
print('------list all existing customization Spec------')
|
||||
existingSpecs = self.specs_svc.list()
|
||||
if (len(existingSpecs) > 0):
|
||||
pprint(existingSpecs)
|
||||
else:
|
||||
print('no specs found')
|
||||
print('------------------------------------------------')
|
||||
|
||||
def getSetCloudinitDataCustomizationSpec(self):
|
||||
print('------get an existing cloud-init data customization Spec------')
|
||||
existingSpecs = self.specs_svc.list()
|
||||
if (len(existingSpecs) > 0):
|
||||
existingSpecName = existingSpecs[0].name
|
||||
existingSpec = self.specs_svc.get(existingSpecName)
|
||||
pprint(existingSpec)
|
||||
# Set a new spec description
|
||||
newSpecDesc =\
|
||||
'{} updated by vapi set() method'.format(existingSpecName)
|
||||
existingSpec.spec.description = newSpecDesc
|
||||
# Set a new metadata
|
||||
metadata =\
|
||||
"""
|
||||
instance-id: test-vm-id-01-updated
|
||||
local-hostname: test-vm-01-updated
|
||||
network:
|
||||
version: 2
|
||||
ethernets:
|
||||
ens160:
|
||||
match:
|
||||
name: ens*
|
||||
dhcp4: yes
|
||||
"""
|
||||
existingSpec.spec.spec.configuration_spec.cloud_config.cloudinit.\
|
||||
metadata = metadata
|
||||
print('------set existing cloud-init data customizationSpec------')
|
||||
self.specs_svc.set(name=existingSpecName, spec=existingSpec.spec)
|
||||
print('{} has been set'.format(existingSpecName))
|
||||
pprint(existingSpec)
|
||||
else:
|
||||
print('no specs found')
|
||||
print('-------------------------------------------------------------')
|
||||
|
||||
def deleteCustomizationSpecs(self):
|
||||
print('-----delete existing customization Specs-----')
|
||||
existingSpecs = self.specs_svc.list()
|
||||
if (len(existingSpecs) > 0):
|
||||
for i in range(len(existingSpecs)):
|
||||
specName = existingSpecs[i].name
|
||||
self.specs_svc.delete(specName)
|
||||
print('{} has been deleted'.format(specName))
|
||||
else:
|
||||
print('no specs found')
|
||||
print('-------------------------------------------------------------')
|
||||
|
||||
|
||||
def main():
|
||||
cloudinitDataCustomizationSpecs = CloudinitDataCustomizationSpecs()
|
||||
cloudinitDataCustomizationSpecs.createSpecWithMetadataInYamlAndUserdata()
|
||||
cloudinitDataCustomizationSpecs.createSpecWithMetadataInJsonAndUserdata()
|
||||
cloudinitDataCustomizationSpecs.createSpecWithMetadataOnly()
|
||||
cloudinitDataCustomizationSpecs.listCustomizationSpecs()
|
||||
cloudinitDataCustomizationSpecs.getSetCloudinitDataCustomizationSpec()
|
||||
cloudinitDataCustomizationSpecs.deleteCustomizationSpecs()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
387
samples/vsphere/vcenter/guest/customizationSpecs.py
Normal file
387
samples/vsphere/vcenter/guest/customizationSpecs.py
Normal file
@ -0,0 +1,387 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
* *******************************************************
|
||||
* Copyright (c) VMware, Inc. 2020. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
* *******************************************************
|
||||
*
|
||||
* DISCLAIMER. THIS PROGRAM IS PROVIDED TO YOU "AS IS" WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, WHETHER ORAL OR WRITTEN,
|
||||
* EXPRESS OR IMPLIED. THE AUTHOR SPECIFICALLY DISCLAIMS ANY IMPLIED
|
||||
* WARRANTIES OR CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY,
|
||||
* NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
"""
|
||||
|
||||
__author__ = 'VMware, Inc.'
|
||||
__copyright__ = 'Copyright 2020 VMware, Inc. All rights reserved.'
|
||||
__vcenter_version__ = '7.0+'
|
||||
|
||||
from pprint import pprint
|
||||
import configparser
|
||||
import os
|
||||
|
||||
from vmware.vapi.vsphere.client import create_vsphere_client
|
||||
from samples.vsphere.common import sample_cli
|
||||
from samples.vsphere.common import sample_util
|
||||
from samples.vsphere.common.ssl_helper import get_unverified_session
|
||||
|
||||
from com.vmware.vcenter.guest_client import (CustomizationSpec,
|
||||
HostnameGenerator,
|
||||
LinuxConfiguration,
|
||||
ConfigurationSpec,
|
||||
GlobalDNSSettings,
|
||||
AdapterMapping,
|
||||
IPSettings,
|
||||
Ipv4,
|
||||
Ipv6,
|
||||
Ipv6Address)
|
||||
from com.vmware.vcenter.guest_client import (WindowsConfiguration,
|
||||
WindowsSysprep,
|
||||
Domain,
|
||||
GuiUnattended,
|
||||
UserData,
|
||||
WindowsNetworkAdapterSettings)
|
||||
|
||||
|
||||
class CustomizationSpecManager(object):
|
||||
"""
|
||||
Demonstrates create/list/get/set/delete customizationSpecs in vCenter
|
||||
Sample Prerequisites: 1 vcenter, no ESXi nor VM needed
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
parser = sample_cli.build_arg_parser()
|
||||
parser.add_argument('-x', '--win_password',
|
||||
action='store',
|
||||
help='windows admin password to be customized')
|
||||
args = sample_util.process_cli_args(parser.parse_args())
|
||||
if args.win_password:
|
||||
self.win_password = args.win_password
|
||||
else:
|
||||
self.win_password = None
|
||||
session = get_unverified_session() if args.skipverification else None
|
||||
self.client = create_vsphere_client(server=args.server,
|
||||
username=args.username,
|
||||
password=args.password,
|
||||
session=session)
|
||||
self.specs_svc = self.client.vcenter.guest.CustomizationSpecs
|
||||
# get customization config
|
||||
self.config = configparser.ConfigParser()
|
||||
self.linCfgPath = os.path.join(os.path.dirname(
|
||||
os.path.realpath(__file__)),
|
||||
'linSpec.cfg')
|
||||
self.winCfgPath = os.path.join(os.path.dirname(
|
||||
os.path.realpath(__file__)),
|
||||
'winSpec.cfg')
|
||||
self.specsAdded = []
|
||||
|
||||
# common method to parse specInfo for linux/windows spec
|
||||
def parseSpecInfo(self):
|
||||
self.specName = self.config['CREATESPEC']['specName']
|
||||
self.specDesc = self.config['CREATESPEC']['specDesc']
|
||||
|
||||
# common method to parse network cfg for linux/windows spec
|
||||
def parseNetwork(self):
|
||||
# parse macAddress
|
||||
self.macAddress = self.config['NETWORK'].get('macAddress')
|
||||
# parse ipv4
|
||||
self.ipv4Type = self.config['NETWORK'].get('ipv4Type', 'DHCP')
|
||||
if self.ipv4Type == 'STATIC':
|
||||
self.ipv4_prefix = self.config['NETWORK'].getint('ipv4_prefix')
|
||||
self.ipv4_gateways = self.config['NETWORK'].get('ipv4_gateways')
|
||||
if self.ipv4_gateways is not None:
|
||||
self.ipv4_gateways = self.ipv4_gateways.split(',')
|
||||
self.ipv4_ip = self.config['NETWORK'].get('ipv4_ip')
|
||||
elif (self.ipv4Type == 'DHCP' or
|
||||
self.ipv4Type == 'USER_INPUT_REQUIRED'):
|
||||
self.ipv4_prefix = None
|
||||
self.ipv4_gateways = None
|
||||
self.ipv4_ip = None
|
||||
else:
|
||||
raise Exception('Wrong ipv4Type "{}"'.format(self.ipv4Type))
|
||||
# parse ipv6
|
||||
self.ipv6Type = self.config['NETWORK'].get('ipv6Type')
|
||||
if self.ipv6Type == 'STATIC':
|
||||
self.ipv6_prefix = self.config['NETWORK'].getint('ipv6_prefix')
|
||||
self.ipv6_gateways = self.config['NETWORK'].get('ipv6_gateways')
|
||||
if self.ipv6_gateways is not None:
|
||||
self.ipv6_gateways = self.ipv6_gateways.split(',')
|
||||
self.ipv6_ip = self.config['NETWORK'].get('ipv6_ip')
|
||||
elif ((self.ipv6Type is None) or (self.ipv4Type == 'DHCP') or
|
||||
(self.ipv4Type == 'USER_INPUT_REQUIRED')):
|
||||
self.ipv6_prefix = None
|
||||
self.ipv6_ip = None
|
||||
self.ipv6_gateways = None
|
||||
else:
|
||||
raise Exception('Wrong ipv6Type "{}"'.format(self.ipv6Type))
|
||||
|
||||
# common method to parse hostname cfg for linux/windows spec
|
||||
def parseHostname(self):
|
||||
# parse hostname generator type
|
||||
self.hostnameType =\
|
||||
self.config['HOSTNAME'].get('hostnameGeneratorType',
|
||||
'VIRTUAL_MACHINE')
|
||||
if (self.hostnameType == 'VIRTUAL_MACHINE' or
|
||||
self.hostnameType == 'USER_INPUT_REQUIRED'):
|
||||
self.prefix = None
|
||||
self.fixedName = None
|
||||
elif self.hostnameType == 'PREFIX':
|
||||
self.prefix = self.config['HOSTNAME'].get('prefix')
|
||||
self.fixedName = None
|
||||
elif self.hostnameType == 'FIXED':
|
||||
self.fixedName = self.config['HOSTNAME'].get('fixedName')
|
||||
self.prefix = None
|
||||
else:
|
||||
raise Exception('Wrong hostnameGeneratorType "{}"'.format(
|
||||
self.hostnameType))
|
||||
|
||||
# common method to parse DNS cfg for linux/windows spec
|
||||
def parseDns(self):
|
||||
self.globalDnsServers = self.config['DNS'].get('dnsServers')
|
||||
if self.globalDnsServers is not None:
|
||||
self.globalDnsServers = self.globalDnsServers.split(',')
|
||||
self.globalDnsSuffixs = self.config['DNS'].get('dnsSuffixs')
|
||||
if self.globalDnsSuffixs is not None:
|
||||
self.globalDnsSuffixs = self.globalDnsSuffixs.split(',')
|
||||
|
||||
def parseWinnics(self):
|
||||
self.netBiosMode = self.config['WINNICS'].get('netBiosMode')
|
||||
self.dnsServers = self.config['WINNICS'].get('dnsServers')
|
||||
if self.dnsServers is not None:
|
||||
self.dnsServers = self.dnsServers.split(',')
|
||||
self.dnsDomain = self.config['WINNICS'].get('dnsDomain')
|
||||
self.winsServers = self.config['WINNICS'].get('winsServers')
|
||||
if self.winsServers is not None:
|
||||
self.winsServers = self.winsServers.split(',')
|
||||
|
||||
def parseLinuxCfg(self):
|
||||
self.config.read(self.linCfgPath)
|
||||
self.parseSpecInfo()
|
||||
self.linSpecName = self.specName
|
||||
self.parseNetwork()
|
||||
self.parseHostname()
|
||||
self.domainName = self.config['LINUXCONFIG'].get('domainName')
|
||||
self.timezone = self.config['LINUXCONFIG'].get('timezone')
|
||||
self.script_text = self.config['LINUXCONFIG'].get('script_text')
|
||||
self.parseDns()
|
||||
|
||||
def parseWinCfg(self):
|
||||
self.config.read(self.winCfgPath)
|
||||
self.parseSpecInfo()
|
||||
self.winSpecName = self.specName
|
||||
self.parseNetwork()
|
||||
self.parseHostname()
|
||||
self.parseDns()
|
||||
self.rebootOption = self.config['WINCONFIG'].get('rebootOption')
|
||||
self.fullName = self.config['WINCONFIG'].get('fullName')
|
||||
self.org = self.config['WINCONFIG'].get('organization')
|
||||
self.productKey = self.config['WINCONFIG'].get('productKey')
|
||||
# parse domain or workgroup
|
||||
self.domainType =\
|
||||
self.config['WINCONFIG'].get('domainType', 'WORKGROUP')
|
||||
if self.domainType == "WORKGROUP":
|
||||
self.workgroup = self.config['WINCONFIG'].get('workgroup')
|
||||
self.domain = None
|
||||
self.domainUser = None
|
||||
self.domainPass = None
|
||||
elif self.domainType == "DOMAIN":
|
||||
self.workgroup = None
|
||||
self.domain = self.config['WINCONFIG'].get('domain')
|
||||
self.domainUser = self.config['WINCONFIG'].get('domainUser')
|
||||
self.domainPass = self.config['WINCONFIG'].get('domainPass')
|
||||
else:
|
||||
raise Exception('Wrong domainType "{}"'.format(self.domainType))
|
||||
self.autoLogon =\
|
||||
self.config['WINCONFIG'].getboolean('autoLogon', False)
|
||||
self.autoLogonCount =\
|
||||
self.config['WINCONFIG'].getint('autoLogonCount', 0)
|
||||
self.timezone = self.config['WINCONFIG'].getint('timezone', 4)
|
||||
# The local Admin password
|
||||
# ### WARNING: USE CLEAR TEXT IN winSpec.cfg AT YOUR OWN RISK!!! ###
|
||||
# Suggested to use "--win_password" command line option instead
|
||||
# It will overrid this value here
|
||||
if not self.win_password:
|
||||
self.win_password = self.config['WINCONFIG'].get('password')
|
||||
self.gui_run_once_commands =\
|
||||
self.config['WINCONFIG'].get('gui_run_once_commands')
|
||||
if self.gui_run_once_commands is not None:
|
||||
self.gui_run_once_commands = self.gui_run_once_commands.split(',')
|
||||
self.sysprepXml = self.config['WINCONFIG'].get('sysprepXml')
|
||||
self.parseWinnics()
|
||||
|
||||
def listCustomizationSpecs(self):
|
||||
"""
|
||||
List CustomizationSpecs present in vc server
|
||||
"""
|
||||
print("------------list--------------")
|
||||
print("List Of CustomizationSpecs:")
|
||||
list_of_specs = self.specs_svc.list()
|
||||
self.specCount = len(list_of_specs)
|
||||
pprint(list_of_specs)
|
||||
|
||||
def createLinuxSpec(self):
|
||||
print("------------create 1 linux Customizationpec----------------")
|
||||
self.parseLinuxCfg()
|
||||
computerName = HostnameGenerator(prefix=self.prefix,
|
||||
fixed_name=self.fixedName,
|
||||
type=HostnameGenerator.Type(
|
||||
self.hostnameType))
|
||||
spec_linuxConfig = LinuxConfiguration(domain=self.domainName,
|
||||
hostname=computerName,
|
||||
time_zone=self.timezone,
|
||||
script_text=self.script_text)
|
||||
spec_configSpec = ConfigurationSpec(linux_config=spec_linuxConfig)
|
||||
# AdapterMapping
|
||||
ipv4Cfg = Ipv4(type=Ipv4.Type(self.ipv4Type), prefix=self.ipv4_prefix,
|
||||
gateways=self.ipv4_gateways, ip_address=self.ipv4_ip)
|
||||
if self.ipv6Type is not None:
|
||||
ipv6addr = [Ipv6Address(prefix=self.ipv6_prefix,
|
||||
ip_address=self.ipv6_ip)]
|
||||
ipv6Cfg = Ipv6(gateways=self.ipv6_gateways, ipv6=ipv6addr,
|
||||
type=Ipv6.Type(self.ipv6Type))
|
||||
else:
|
||||
ipv6Cfg = None
|
||||
ipSettings = IPSettings(windows=None, ipv4=ipv4Cfg, ipv6=ipv6Cfg)
|
||||
adapterMappingList = [AdapterMapping(adapter=ipSettings,
|
||||
mac_address=self.macAddress)]
|
||||
# dns_settings
|
||||
dns_settings = GlobalDNSSettings(dns_servers=self.globalDnsServers,
|
||||
dns_suffix_list=self.globalDnsSuffixs)
|
||||
# CreateSpec
|
||||
linspec_spec = CustomizationSpec(configuration_spec=spec_configSpec,
|
||||
interfaces=adapterMappingList,
|
||||
global_dns_settings=dns_settings)
|
||||
lin_create_spec = self.specs_svc.CreateSpec(name=self.specName,
|
||||
description=self.specDesc,
|
||||
spec=linspec_spec)
|
||||
# svc Create
|
||||
self.specs_svc.create(spec=lin_create_spec)
|
||||
# append it to existing list, for delete and cleanup
|
||||
self.specsAdded.append(self.specName)
|
||||
# list after create
|
||||
self.listCustomizationSpecs()
|
||||
print("----------------------------")
|
||||
|
||||
def createWinSpec(self):
|
||||
print("------------create 1 windows CustomizationSpec----------------")
|
||||
self.parseWinCfg()
|
||||
# IPSettings
|
||||
ipv4Cfg = Ipv4(type=Ipv4.Type(self.ipv4Type), prefix=self.ipv4_prefix,
|
||||
gateways=self.ipv4_gateways, ip_address=self.ipv4_ip)
|
||||
if self.ipv6Type is not None:
|
||||
ipv6addr = [Ipv6Address(prefix=self.ipv6_prefix,
|
||||
ip_address=self.ipv6_ip)]
|
||||
ipv6Cfg = Ipv6(gateways=self.ipv6_gateways, ipv6=ipv6addr,
|
||||
type=Ipv6.Type(self.ipv6Type))
|
||||
else:
|
||||
ipv6Cfg = None
|
||||
windowsNicSettings = WindowsNetworkAdapterSettings(
|
||||
net_bios_mode=self.netBiosMode, dns_servers=self.dnsServers,
|
||||
dns_domain=self.dnsDomain, wins_servers=self.winsServers)
|
||||
ipSettings = IPSettings(windows=windowsNicSettings,
|
||||
ipv4=ipv4Cfg, ipv6=ipv6Cfg)
|
||||
# AdapterMapping
|
||||
adapterMappingList = [AdapterMapping(adapter=ipSettings,
|
||||
mac_address=self.macAddress)]
|
||||
|
||||
# WindowsConfiguration
|
||||
myReboot = WindowsConfiguration.RebootOption(self.rebootOption)
|
||||
computerName = HostnameGenerator(prefix=self.prefix,
|
||||
fixed_name=self.fixedName,
|
||||
type=HostnameGenerator.Type(
|
||||
self.hostnameType))
|
||||
userData = UserData(computer_name=computerName,
|
||||
product_key=self.productKey,
|
||||
full_name=self.fullName,
|
||||
organization=self.org)
|
||||
myDomain = Domain(domain=self.domain, workgroup=self.workgroup,
|
||||
domain_username=self.domainUser,
|
||||
domain_password=self.domainPass,
|
||||
type=Domain.Type(self.domainType))
|
||||
guiUnattended = GuiUnattended(auto_logon_count=self.autoLogonCount,
|
||||
auto_logon=self.autoLogon,
|
||||
time_zone=self.timezone,
|
||||
password=self.win_password)
|
||||
mySysprep = WindowsSysprep(domain=myDomain,
|
||||
gui_unattended=guiUnattended,
|
||||
user_data=userData,
|
||||
gui_run_once_commands=self.
|
||||
gui_run_once_commands)
|
||||
winCfg = WindowsConfiguration(reboot=myReboot,
|
||||
sysprep=mySysprep,
|
||||
sysprep_xml=self.sysprepXml)
|
||||
# CustomizationSpec
|
||||
spec_configSpec = ConfigurationSpec(windows_config=winCfg)
|
||||
dns_settings = GlobalDNSSettings(dns_servers=self.globalDnsServers,
|
||||
dns_suffix_list=self.globalDnsSuffixs)
|
||||
winspec_spec = CustomizationSpec(configuration_spec=spec_configSpec,
|
||||
interfaces=adapterMappingList,
|
||||
global_dns_settings=dns_settings)
|
||||
# CreateSpec
|
||||
win_create_spec = self.specs_svc.CreateSpec(name=self.specName,
|
||||
description=self.specDesc,
|
||||
spec=winspec_spec)
|
||||
# list before create
|
||||
self.listCustomizationSpecs()
|
||||
existingSpecCount = self.specCount
|
||||
# svc Create
|
||||
self.specs_svc.create(spec=win_create_spec)
|
||||
# append it to existing list, for delete and cleanup
|
||||
self.specsAdded.append(self.specName)
|
||||
# list after create
|
||||
self.listCustomizationSpecs()
|
||||
print("----------------------------")
|
||||
newSpecCount = self.specCount
|
||||
if(newSpecCount != existingSpecCount + 1):
|
||||
raise Exception('Error createSpec due to spec count={}'.
|
||||
format(newSpecCount))
|
||||
|
||||
def getSetSpec(self):
|
||||
print("-----------Get existing Spec------------")
|
||||
# Get created specs, modify timezone and description of the linSpec
|
||||
linSpec = self.specs_svc.get(self.linSpecName)
|
||||
pprint(linSpec)
|
||||
winSpec = self.specs_svc.get(self.winSpecName)
|
||||
pprint(winSpec)
|
||||
linSpec.spec.spec.configuration_spec.linux_config.time_zone =\
|
||||
'Europe/London'
|
||||
linSpec.spec.description = linSpec.spec.description +\
|
||||
" modified by vapi set() method"
|
||||
print("-----------Set to modify existing linSpec------------")
|
||||
self.specs_svc.set(name=self.linSpecName, spec=linSpec.spec)
|
||||
# Now check again if its timezone and description has changed
|
||||
print("-----------Get the modified linSpec------------")
|
||||
linSpec = self.specs_svc.get(self.linSpecName)
|
||||
pprint(linSpec)
|
||||
print("----------------------------")
|
||||
|
||||
def deleteSpec(self):
|
||||
print("-----------Delete created spec for cleanup------------")
|
||||
print("-----------before delete------------")
|
||||
self.listCustomizationSpecs()
|
||||
existingSpecCount = self.specCount
|
||||
for specName in self.specsAdded:
|
||||
self.specs_svc.delete(specName)
|
||||
existingSpecCount -= 1
|
||||
# list again, there should be []
|
||||
print("-----------after delete------------")
|
||||
self.listCustomizationSpecs()
|
||||
newSpecCount = self.specCount
|
||||
print("----------------------------")
|
||||
if(newSpecCount != existingSpecCount):
|
||||
raise Exception('Error deleteSpec due to current specCount {}!={}'.
|
||||
format(newSpecCount, existingSpecCount))
|
||||
|
||||
|
||||
def main():
|
||||
myCustSpecMgr = CustomizationSpecManager()
|
||||
myCustSpecMgr.listCustomizationSpecs()
|
||||
myCustSpecMgr.createLinuxSpec()
|
||||
myCustSpecMgr.createWinSpec()
|
||||
myCustSpecMgr.getSetSpec()
|
||||
myCustSpecMgr.deleteSpec()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
* *******************************************************
|
||||
* Copyright (c) VMware, Inc. 2020. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
* *******************************************************
|
||||
*
|
||||
* DISCLAIMER. THIS PROGRAM IS PROVIDED TO YOU "AS IS" WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, WHETHER ORAL OR WRITTEN,
|
||||
* EXPRESS OR IMPLIED. THE AUTHOR SPECIFICALLY DISCLAIMS ANY IMPLIED
|
||||
* WARRANTIES OR CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY,
|
||||
* NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
"""
|
||||
|
||||
__author__ = 'VMware, Inc.'
|
||||
__copyright__ = 'Copyright 2020 VMware, Inc. All rights reserved.'
|
||||
__vcenter_version__ = '7.0+'
|
||||
|
||||
from pprint import pprint
|
||||
import os
|
||||
|
||||
from vmware.vapi.vsphere.client import create_vsphere_client
|
||||
from samples.vsphere.common import sample_cli
|
||||
from samples.vsphere.common import sample_util
|
||||
from samples.vsphere.common.ssl_helper import get_unverified_session
|
||||
|
||||
|
||||
class CustomizationSpecManager(object):
|
||||
"""
|
||||
Demonstrates import/export customizationSpecs in vCenter
|
||||
Sample Prerequisites: 1 vcenter, no ESXi nor VM needed
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
parser = sample_cli.build_arg_parser()
|
||||
args = sample_util.process_cli_args(parser.parse_args())
|
||||
session = get_unverified_session() if args.skipverification else None
|
||||
self.client = create_vsphere_client(server=args.server,
|
||||
username=args.username,
|
||||
password=args.password,
|
||||
session=session)
|
||||
self.specs_svc = self.client.vcenter.guest.CustomizationSpecs
|
||||
filePath = os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
||||
'sample_import.json')
|
||||
with open(filePath, 'r') as f:
|
||||
self.jsonDataRaw = f.read()
|
||||
self.specName = 'defaultCustSpec01'
|
||||
self.specsAdded = []
|
||||
|
||||
def listCustomizationSpecs(self):
|
||||
"""
|
||||
List CustomizationSpecs present in vc server
|
||||
"""
|
||||
print("------------list--------------")
|
||||
print("List Of CustomizationSpecs:")
|
||||
list_of_specs = self.specs_svc.list()
|
||||
pprint(list_of_specs)
|
||||
|
||||
def importSpecTest(self):
|
||||
print("--------import and create Customizationpec from json--------")
|
||||
# CreateSpec
|
||||
create_spec = self.specs_svc.import_specification(self.jsonDataRaw)
|
||||
# svc Create
|
||||
self.specs_svc.create(spec=create_spec)
|
||||
# append it to existing list, for delete and cleanup
|
||||
self.specsAdded.append(self.specName)
|
||||
# list after create
|
||||
self.listCustomizationSpecs()
|
||||
print("----------------------------")
|
||||
|
||||
def exportSpecTest(self):
|
||||
print("-----------Get existing Spec------------")
|
||||
# Get a spec, modify its timezone and description
|
||||
mySpecXml = self.specs_svc.export(self.specName, 'XML')
|
||||
pprint(mySpecXml)
|
||||
mySpecJson = self.specs_svc.export(self.specName, 'JSON')
|
||||
pprint(mySpecJson)
|
||||
print("----------------------------")
|
||||
|
||||
def deleteSpecTest(self):
|
||||
print("-----------Delete created spec for cleanup------------")
|
||||
print("-----------before delete------------")
|
||||
self.listCustomizationSpecs()
|
||||
for specName in self.specsAdded:
|
||||
self.specs_svc.delete(specName)
|
||||
# list again, there should be []
|
||||
print("-----------after delete------------")
|
||||
self.listCustomizationSpecs()
|
||||
print("----------------------------")
|
||||
|
||||
|
||||
def main():
|
||||
myCustSpecMgr = CustomizationSpecManager()
|
||||
myCustSpecMgr.listCustomizationSpecs()
|
||||
myCustSpecMgr.importSpecTest()
|
||||
myCustSpecMgr.exportSpecTest()
|
||||
myCustSpecMgr.deleteSpecTest()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
51
samples/vsphere/vcenter/guest/linSpec.cfg
Normal file
51
samples/vsphere/vcenter/guest/linSpec.cfg
Normal file
@ -0,0 +1,51 @@
|
||||
[CREATESPEC]
|
||||
specName=testCreateLinSpec1
|
||||
specDesc=This is a linux customizationSpec created by vAPI
|
||||
|
||||
[HOSTNAME]
|
||||
# valid types are: FIXED, PREFIX, VIRTUAL_MACHINE, USER_INPUT_REQUIRED
|
||||
hostnameGeneratorType=VIRTUAL_MACHINE
|
||||
# If hostnameGeneratorType is "PREFIX", prefix must be set to some string
|
||||
#prefix=
|
||||
# If hostnameGeneratorType is "FIXED", fixedName must be set to the hostname string
|
||||
#fixedName=
|
||||
|
||||
[LINUXCONFIG]
|
||||
domainName=test.abc.com
|
||||
# valid timezone list: https://kb.vmware.com/s/article/2145518
|
||||
timezone=Asia/Shanghai
|
||||
# should be some valid bash/shell script txt or empty
|
||||
#scriptText=
|
||||
|
||||
|
||||
[NETWORK]
|
||||
### MacAddress ###
|
||||
# macAddress is optional
|
||||
# macAddress=fc:00:0a:33:22:11
|
||||
|
||||
### IPV4 ###
|
||||
# valid types are: DHCP, STATIC, USER_INPUT_REQUIRED.
|
||||
# If use "STATIC", then must also input "prefix, gateways=None, ip_address="
|
||||
## sample DHCP ipv4Type ##
|
||||
ipv4Type=DHCP
|
||||
## sample STATIC ipv4Type ##
|
||||
#ipv4Type=STATIC
|
||||
#ipv4_prefix=31
|
||||
#ipv4_gateways=192.168.11.13
|
||||
#ipv4_ip=192.168.11.1
|
||||
|
||||
### IPV6 ###
|
||||
# valid types are: DHCP, STATIC, USER_INPUT_REQUIRED.
|
||||
# If use "STATIC", then must also input "prefix, gateways=None, ip_address="
|
||||
## sample DHCP ipv6Type ##
|
||||
#ipv6Type=DHCP
|
||||
## sample STATIC ipv6Type ##
|
||||
#ipv6Type=STATIC
|
||||
#ipv6_prefix=128
|
||||
#ipv6_gateways=fc00:10:31:11::1
|
||||
#ipv6_ip=fc00:10:31:11::34
|
||||
|
||||
|
||||
[DNS]
|
||||
dnsServers=10.1.2.3,8.8.8.8
|
||||
dnsSuffixs=test.abc.com,test2.com
|
106
samples/vsphere/vcenter/guest/sample_import.json
Normal file
106
samples/vsphere/vcenter/guest/sample_import.json
Normal file
@ -0,0 +1,106 @@
|
||||
{
|
||||
"STRUCTURE": {
|
||||
"com.vmware.vcenter.guest.customization_specs.spec": {
|
||||
"description": "This is a generic ipv4 customizationSpec for linux VM customization. Created by VIM API",
|
||||
"name": "defaultCustSpec01",
|
||||
"spec": {
|
||||
"STRUCTURE": {
|
||||
"com.vmware.vcenter.guest.customization_spec": {
|
||||
"configuration_spec": {
|
||||
"STRUCTURE": {
|
||||
"com.vmware.vcenter.guest.configuration_spec": {
|
||||
"linux_config": {
|
||||
"OPTIONAL": {
|
||||
"STRUCTURE": {
|
||||
"com.vmware.vcenter.guest.linux_configuration": {
|
||||
"domain": "VMWare.com",
|
||||
"hostname": {
|
||||
"STRUCTURE": {
|
||||
"com.vmware.vcenter.guest.hostname_generator": {
|
||||
"fixed_name": {
|
||||
"OPTIONAL": "vapiCustName123"
|
||||
},
|
||||
"prefix": {
|
||||
"OPTIONAL": null
|
||||
},
|
||||
"type": "FIXED"
|
||||
}
|
||||
}
|
||||
},
|
||||
"time_zone": {
|
||||
"OPTIONAL": null
|
||||
},
|
||||
"script_text": {
|
||||
"OPTIONAL": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"windows_config": {
|
||||
"OPTIONAL": null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"global_DNS_settings": {
|
||||
"STRUCTURE": {
|
||||
"com.vmware.vcenter.guest.global_DNS_settings": {
|
||||
"dns_servers": {
|
||||
"OPTIONAL": []
|
||||
},
|
||||
"dns_suffix_list": {
|
||||
"OPTIONAL": []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"interfaces": [
|
||||
{
|
||||
"STRUCTURE": {
|
||||
"com.vmware.vcenter.guest.adapter_mapping": {
|
||||
"adapter": {
|
||||
"STRUCTURE": {
|
||||
"com.vmware.vcenter.guest.IP_settings": {
|
||||
"ipv4": {
|
||||
"OPTIONAL": {
|
||||
"STRUCTURE": {
|
||||
"com.vmware.vcenter.guest.ipv4": {
|
||||
"gateways": {
|
||||
"OPTIONAL": [
|
||||
"192.168.12.1"
|
||||
]
|
||||
},
|
||||
"ip_address": {
|
||||
"OPTIONAL": "192.168.12.11"
|
||||
},
|
||||
"prefix": {
|
||||
"OPTIONAL": 31
|
||||
},
|
||||
"type": "STATIC"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ipv6": {
|
||||
"OPTIONAL": null
|
||||
},
|
||||
"windows": {
|
||||
"OPTIONAL": null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mac_address": {
|
||||
"OPTIONAL": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
21
samples/vsphere/vcenter/guest/sample_metadata.json
Normal file
21
samples/vsphere/vcenter/guest/sample_metadata.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"local-hostname": "test-vm-01",
|
||||
"instance-id": "test-vm-id-01",
|
||||
"network": {
|
||||
"version":2,
|
||||
"ethernets": {
|
||||
"nics": {
|
||||
"match": {
|
||||
"name": "eth*"
|
||||
},
|
||||
"nameservers": {
|
||||
"addresses": ["127.0.0.53"],
|
||||
"search": ["eng.vmware.com", "vmware.com"]
|
||||
},
|
||||
"gateway4": "10.182.15.255",
|
||||
"dhcp4": false,
|
||||
"addresses": ["10.182.12.25/24"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
samples/vsphere/vcenter/guest/sample_metadata.yaml
Normal file
9
samples/vsphere/vcenter/guest/sample_metadata.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
instance-id: test-vm-id-01
|
||||
local-hostname: test-vm-01
|
||||
network:
|
||||
version: 2
|
||||
ethernets:
|
||||
nics:
|
||||
match:
|
||||
name: eth*
|
||||
dhcp4: yes
|
9
samples/vsphere/vcenter/guest/sample_userdata
Normal file
9
samples/vsphere/vcenter/guest/sample_userdata
Normal file
@ -0,0 +1,9 @@
|
||||
#cloud-config
|
||||
# See more userdata examples at:
|
||||
# https://cloudinit.readthedocs.io/en/latest/topics/examples.html
|
||||
write_files:
|
||||
- encoding: gzip
|
||||
content: !!binary |
|
||||
H4sIAIDb/U8C/1NW1E/KzNMvzuBKTc7IV8hIzcnJVyjPL8pJ4QIA6N+MVxsAAAA=
|
||||
path: /usr/bin/hello
|
||||
permissions: '0755'
|
87
samples/vsphere/vcenter/guest/winSpec.cfg
Normal file
87
samples/vsphere/vcenter/guest/winSpec.cfg
Normal file
@ -0,0 +1,87 @@
|
||||
[CREATESPEC]
|
||||
specName=testWinSpec1
|
||||
specDesc=This is a windows customizationSpec created by vAPI
|
||||
|
||||
[HOSTNAME]
|
||||
# valid types are: FIXED, PREFIX, VIRTUAL_MACHINE, USER_INPUT_REQUIRED
|
||||
hostnameGeneratorType=VIRTUAL_MACHINE
|
||||
# If hostnameGeneratorType is "PREFIX", prefix must be set to some string
|
||||
#prefix=''
|
||||
# If hostnameGeneratorType is "FIXED", fixedName must be set to the hostname string
|
||||
#fixedName=''
|
||||
|
||||
[WINCONFIG]
|
||||
# valid options are: REBOOT, NO_REBOOT, SHUTDOWN
|
||||
rebootOption=REBOOT
|
||||
productKey=
|
||||
fullName=AComputerNameFull
|
||||
organization=testCome
|
||||
|
||||
# domain or worgroup, valid type are: WORKGROUP, DOMAIN
|
||||
domainType=WORKGROUP
|
||||
# if type is "WORKGROUP", workgroup field must be set to some workgroup name str #
|
||||
workgroup=WORKGROUP
|
||||
# if type is "DOMAIN", domain name, domainUser, domainPassword should be set #
|
||||
#domain=
|
||||
#domainUser=
|
||||
#domainPass=
|
||||
|
||||
# valid timezone list: https://support.microsoft.com/en-us/help/973627/microsoft-time-zone-index-values
|
||||
# "2" means "(GMT-10:00) Hawaii
|
||||
# "4" means "(GMT-08:00) Pacific Time (US and Canada); Tijuana"
|
||||
# "D2" means "(GMT+08:00) Beijing, Chongqing, Hong Kong, Urumqi"
|
||||
timezone=2
|
||||
|
||||
# auto logon after customization, if autoLogon is True, then admin password must be set
|
||||
autoLogonCount=0
|
||||
autoLogon=False
|
||||
|
||||
# The local Admin password
|
||||
### WARNING: USE CLEAR TEXT HERE AT YOUR OWN RISK!!! ###
|
||||
### Suggested to use "--win_password" command line option instead
|
||||
### It will overrid this value here
|
||||
# password=ASecurePass!
|
||||
|
||||
# optional, TBD
|
||||
# gui_run_once_commands=
|
||||
# optional, TBD
|
||||
# sysprepXml=
|
||||
|
||||
[NETWORK]
|
||||
### MacAddress ###
|
||||
# macAddress is optional
|
||||
# macAddress=fc:00:0a:33:22:11
|
||||
|
||||
### IPV4 ###
|
||||
# valid types are: DHCP, STATIC, USER_INPUT_REQUIRED.
|
||||
# If use "STATIC", then must also input "prefix, gateways=None, ip_address="
|
||||
## sample DHCP ipv4Type ##
|
||||
#ipv4Type=DHCP
|
||||
## sample STATIC ipv4Type ##
|
||||
ipv4Type=STATIC
|
||||
ipv4_prefix=31
|
||||
ipv4_gateways=192.168.11.13
|
||||
ipv4_ip=192.168.11.1
|
||||
|
||||
### IPV6 ###
|
||||
# valid types are: DHCP, STATIC, USER_INPUT_REQUIRED.
|
||||
# If use "STATIC", then must also input "prefix, gateways=None, ip_address="
|
||||
## sample DHCP ipv6Type ##
|
||||
#ipv6Type=DHCP
|
||||
## sample STATIC ipv6Type ##
|
||||
ipv6Type=STATIC
|
||||
ipv6_prefix=128
|
||||
ipv6_ip=fc00:10:31:11::34
|
||||
|
||||
|
||||
[WINNICS]
|
||||
# Valid values: ENABLE, DISABLE, USE_DHCP
|
||||
netBiosMode=ENABLE
|
||||
dnsServers=10.11.0.1,8.8.8.8
|
||||
dnsDomain=testabc.com
|
||||
winsServers=192.168.1.113,10.11.0.1
|
||||
|
||||
|
||||
[DNS]
|
||||
dnsServers=10.1.2.3,8.8.8.8
|
||||
dnsSuffixs=test.abc.com,test2.com
|
6
setup.py
6
setup.py
@ -13,9 +13,9 @@ setup(name='vSphere Automation SDK',
|
||||
install_requires=[
|
||||
'lxml >= 4.3.0',
|
||||
'pyVmomi >= 6.7',
|
||||
'vapi-runtime @ file://localhost/{}/lib/vapi-runtime/vapi_runtime-2.25.0-py2.py3-none-any.whl'.format(os.getcwd()),
|
||||
'vapi-client-bindings @ file://localhost/{}/lib/vapi-client-bindings/vapi_client_bindings-3.6.0-py2.py3-none-any.whl'.format(os.getcwd()),
|
||||
'vapi-common-client @ file://localhost/{}/lib/vapi-common-client/vapi_common_client-2.25.0-py2.py3-none-any.whl'.format(os.getcwd()),
|
||||
'vapi-runtime @ file://localhost/{}/lib/vapi-runtime/vapi_runtime-2.30.0-py2.py3-none-any.whl'.format(os.getcwd()),
|
||||
'vapi-client-bindings @ file://localhost/{}/lib/vapi-client-bindings/vapi_client_bindings-3.7.0-py2.py3-none-any.whl'.format(os.getcwd()),
|
||||
'vapi-common-client @ file://localhost/{}/lib/vapi-common-client/vapi_common_client-2.30.0-py2.py3-none-any.whl'.format(os.getcwd()),
|
||||
'vmc-client-bindings @ file://localhost/{}/lib/vmc-client-bindings/vmc_client_bindings-1.52.0-py2.py3-none-any.whl'.format(os.getcwd()),
|
||||
'nsx-python-sdk @ file://localhost/{}/lib/nsx-python-sdk/nsx_python_sdk-3.1.2.1.1-py2.py3-none-any.whl'.format(os.getcwd()),
|
||||
'nsx-policy-python-sdk @ file://localhost/{}/lib/nsx-policy-python-sdk/nsx_policy_python_sdk-3.1.2.1.1-py2.py3-none-any.whl'.format(os.getcwd()),
|
||||
|
Loading…
Reference in New Issue
Block a user