Table of Contents |
---|
SaltStack vSphere Module Setting Guides
Installation
PYVMOMI
PyVmomi can be installed via pip3:
...
CloudHub Portal을 운영중인 Host에 아래와 같이 Package를 설치합니다.
root 권한에서 작업합니다.
Pyvmomi 설치
VMware vSphere API Python Bindings
Code Block language bash $ pip3 install pyVmomi
VMware
...
vSphere vCLI 설치
vCLI 설치전 설치 전 필수 소프트웨어 설치설치합니다.
Code Block $ yum install e2fsprogs-devel libuuid-devel openssl-devel perl-devel $ yum install glibc.i686 zlib.i686 $ yum install perl-XML-LibXML libncurses.so.5 perl-Crypt-SSLeay $ yum -y install perl-Socket6 $ yum -y install cpan $ yum -y install gcc-c++ $ PERL_MM_USE_DEFAULT=1 cpan install BINGOS/ExtUtils-MakeMaker-6.96.tar.gz LEONT/Module-Build-0.4205.tar.gz JRM/UUID-0.28.tar.gz ESAYM/Time-Piece-1.3401.tar.gz PERIGRIN/XML-NamespaceSupport-1.12.tar.gz SHLOMIF/IO-Socket-INET6-2.72.tar.gz
vSphere vCLI Package 설치
1 단계 : vCLI 설치 Package 다운로드다운로드합니다.
Info |
---|
Download URL : https://code.vmware.com/web/tool/6.7/vsphere-cli |
2 단계 : root 로 로그인
...
|
2 단계 : 다운로드한 vCLI 압축 해제해제합니다.
Code Block | ||
---|---|---|
| ||
$ tar zxvf <file-path>/VMware-vSphere-CLI-6.7.0-8156551.x86_64.tar.gz -C <file-path> |
4 3 단계 : 설치프로그램 실행설치 프로그램 실행합니다.
Code Block | ||
---|---|---|
| ||
$ sudo <file-path>/vmware-vsphere-cli-distrib/vmware-install.pl |
5 4 단계 : 라이센스 조항에 동의 하려면 yes하고 동의하기 위해 yes 입력하고 Enter
Info |
---|
설치 관리자는 CPAN에 연결하고 필수 소프트웨어를 설치합니다. 연결하는 연결하는 데 시간이 오래 걸릴 수 있습니다. |
6 5 단계 : 설치 경로를 지정하고 Enter
Info |
---|
Default Path : /usr/bin |
7 6 단계 : vCLI 설치 확인
Code Block |
---|
$ esxcli -s <vCenter Server or ESXi host> -u <username> -p <password> -h <host-location> system syslog config get |
Note |
---|
위 명령어를 입력하면 Certificate error. 와 함께 thumbprint : xx:xx:xx:xx:xx … 가 출력되면 아래와 같이 thumbprint를 credstore에 추가함 |
thumbprint 추가
Code Block |
---|
$ /usr/lib/vmware-vcli/apps/general/credstore_admin.pl add --server <host-location> --thumbprint <thumbprint> |
Salt minion 서비스 Python 환경변수 추가
Code Block |
---|
$ vim /usr/lib/systemd/system/salt-minion.service
# [Service]에 Python3.6 환경변수 추가
Environment="PYTHONPATH=/usr/local/lib/python3.6/site-packages:/usr/lib/python3.6/site-packages"
$ systemctl daemon-reload |
Salt minion Source 수정
init.py Source의 def ignores_kwargs 수정
Warning |
---|
Salt Version 3001.1 이상 버전일 경우 불필요 |
Code Block |
---|
$ vim /usr/lib/python3.6/site-packages/salt/utils/decorators/init.py
def ignores_kwargs(*kwarg_names):
'''
Decorator to filter out unexpected keyword arguments from the call
kwarg_names:
List of argument names to ignore
'''
#print(kwarg_names)
def _ignores_kwargs(fn):
@wraps(fn)
def __ignores_kwargs(*args, **kwargs):
log.trace(f'args: {args}')
log.trace(f'kwargs: {kwargs}')
if args:
ret_fn = fn(*args)
else:
kwargs_filtered = kwargs['__pub_arg'][0].copy()
log.trace(f'Before kwargs_filtered 1: {kwargs_filtered}')
for name in kwarg_names:
log.trace(name)
if name in kwargs_filtered:
del kwargs_filtered[name]
log.trace(f'After kwargs_filtered: {kwargs_filtered}')
ret_fn = fn(**kwargs_filtered)
return ret_fn
return __ignores_kwargs
return _ignores_kwargs |
vsphere.py Source 추가
Code Block |
---|
$ vim /usr/lib/python3.6/site-packages/salt/modules/vsphere.py |
vSphere 정보 조회 관련 소스
Code Block | ||
---|---|---|
| ||
@depends(HAS_PYVMOMI)
@ignores_kwargs('credstore')
def vsphere_info_all(host, username, password, protocol=None, port=None):
service_instance = salt.utils.vmware.get_service_instance(host=host,
username=username,
password=password,
protocol=protocol,
port=port)
content = service_instance.RetrieveContent()
datacenter_properties = [
"name",
]
datacenter_list = get_datacenters(service_instance, datacenter_properties, content.rootFolder)
hw_grain_data = {}
hw_grain_data['vcenter'] = host
hw_grain_data['datacenters'] = []
for datacenter in datacenter_list:
datacenter_data = {}
datacenter_data['name'] = datacenter['name']
totalDsCapacity = 0
totalFreeSpace = 0
datacenterTotalCpu = 0
datacenterTotalMemory = 0
datacenterTotalCpuUsage = 0
datacenterTotalMemoryUsage = 0
datacenterClusterCount = 0
datacenterHostCount = 0
datacenterVmCount = 0
datastore_list = get_datastores(service_instance, datacenter['object'])
datacenter_data['datastores'] = []
for datastore in datastore_list:
datastore_data = {}
datastore_data['name'] = datastore['name']
datastore_data['capacity'] = datastore['summary.capacity']
datastore_data['space'] = datastore['summary.freeSpace']
datastore_data['type'] = datastore['summary.type']
datastore_data['mode'] = datastore['summary.maintenanceMode']
totalDsCapacity += datastore['summary.capacity']
totalFreeSpace += datastore['summary.freeSpace']
datacenter_data['datastores'].append(datastore_data)
datacenter_data['storage_capacity'] = totalDsCapacity
datacenter_data['storage_usage'] = totalDsCapacity - totalFreeSpace
datacenter_data['storage_space'] = totalFreeSpace
cluster_list = get_clusters(service_instance, datacenter['object'])
datacenter_data['clusters'] = []
for cluster in cluster_list:
cluster_data = {}
clusterVmCount = 0
cluster_data['name'] = cluster['name']
cluster_data['cpu_capacity'] = cluster['summary.totalCpu']*1000000
cluster_data['memory_capacity'] = cluster['summary.totalMemory']
datacenterTotalCpu += cluster['summary.totalCpu']*1000000
datacenterTotalMemory += cluster['summary.totalMemory']
cluster_data['cpu_core'] = cluster['summary.numCpuCores']
cluster_data['host_count'] = cluster['summary.numHosts']
datacenterHostCount += cluster_data['host_count']
totalDsCapacity = 0
totalFreeSpace = 0
cluster_datastore_list = get_datastores(service_instance, cluster['object'])
cluster_data['datastores'] = []
for clusterDsObj in cluster_datastore_list:
datastore_data = {}
datastore_data['name'] = clusterDsObj['name']
datastore_data['capacity'] = clusterDsObj['summary.capacity']
datastore_data['space'] = clusterDsObj['summary.freeSpace']
datastore_data['type'] = clusterDsObj['summary.type']
datastore_data['mode'] = clusterDsObj['summary.maintenanceMode']
totalDsCapacity += clusterDsObj['summary.capacity']
totalFreeSpace += clusterDsObj['summary.freeSpace']
cluster_data['datastores'].append(datastore_data)
cluster_data['storage_capacity'] = totalDsCapacity
cluster_data['storage_usage'] = totalDsCapacity - totalFreeSpace
cluster_data['storage_space'] = totalFreeSpace
host_list = get_hosts(service_instance, cluster['object'])
cluster_data['hosts'] = []
clusterTotalCpuUsage = 0
clusterTotalMemoryUsage = 0
for host in host_list:
host_data = {}
hostVmCount = 0
host_data['name'] = host['name']
host_data['powerState'] = host['runtime.powerState']
host_data['vender'] = host['hardware.systemInfo.vendor']
host_data['model'] = host['hardware.systemInfo.model']
if host['runtime.powerState'] == 'poweredOn':
overallCpuUsage = host['summary.quickStats.overallCpuUsage']*1000000
overallMemoryUsage = host['summary.quickStats.overallMemoryUsage']*1048576
cpuCapacity = host['hardware.cpuInfo.hz'] * host['hardware.cpuInfo.numCpuCores']
cpuSpace = cpuCapacity - overallCpuUsage
memorySize = host['hardware.memorySize']
memorySpace = host['hardware.memorySize'] - overallMemoryUsage
host_data['cpu_name'] = host['hardware.cpuPkg'][0].description
host_data['cpu_core'] = host['hardware.cpuInfo.numCpuCores']
host_data['cpu_capacity'] = cpuCapacity
host_data['cpu_usage'] = overallCpuUsage
host_data['cpu_space'] = cpuSpace
clusterTotalCpuUsage += overallCpuUsage
host_data['memory_capacity'] = memorySize
host_data['memory_usage'] = overallMemoryUsage
host_data['memory_space'] = memorySpace
clusterTotalMemoryUsage += overallMemoryUsage
totalDsCapacity = 0
totalFreeSpace = 0
host_datastore_list = get_datastores(service_instance, host['object'])
host_data['datastores'] = []
for hostDsObj in host_datastore_list:
host_datastore_data = {}
host_datastore_data['name'] = hostDsObj['name']
host_datastore_data['capacity'] = hostDsObj['summary.capacity']
host_datastore_data['space'] = hostDsObj['summary.freeSpace']
host_datastore_data['type'] = hostDsObj['summary.type']
host_datastore_data['mode'] = hostDsObj['summary.maintenanceMode']
host_data['datastores'].append(host_datastore_data)
totalDsCapacity += hostDsObj['summary.capacity']
totalFreeSpace += hostDsObj['summary.freeSpace']
host_data['datastores'].append(host_datastore_data)
host_data['storage_capacity'] = totalDsCapacity
host_data['storage_usage'] = totalDsCapacity - totalFreeSpace
host_data['storage_space'] = totalFreeSpace
vm_list = get_vms(service_instance, host['object'])
host_data['vms'] = []
for vm in vm_list:
if vm['summary.config.template'] == False:
vm_data = {}
vm_data['name'] = vm['name']
vm_data['moid'] = vm['object']._moId
vm_data['storage_usage'] = vm['summary.storage.committed']
vm_data['os'] = vm['config.guestFullName']
vm_data['guestId'] = vm['config.guestId']
vm_data['cpu_usage'] = vm['summary.quickStats.overallCpuUsage']*1000000
vm_data['memory_usage'] = vm['summary.quickStats.guestMemoryUsage']*1048576
vm_data['vmPathName'] = vm['config.files.vmPathName']
vm_data['power_state'] = vm['summary.runtime.powerState']
vm_data['memoryMB'] = vm['config.hardware.memoryMB']
vm_data['numCPU'] = vm['config.hardware.numCPU']
if vm['guest.net']:
net = vm['guest.net']
for objNet in net:
if hasattr(objNet.ipConfig, 'ipAddress'):
ipAddress = objNet.ipConfig.ipAddress
for objAddr in ipAddress:
if objAddr.state == 'preferred':
vm_data['ip_address'] = objAddr.ipAddress
host_data['vms'].append(vm_data)
hostVmCount += 1
host_data['vm_count'] = hostVmCount
clusterVmCount += hostVmCount
cluster_data['hosts'].append(host_data)
cluster_data['vm_count'] = clusterVmCount
datacenterVmCount += clusterVmCount
cluster_data['cpu_usage'] = clusterTotalCpuUsage
cluster_data['memory_usage'] = clusterTotalMemoryUsage
datacenterTotalCpuUsage += clusterTotalCpuUsage
datacenterTotalMemoryUsage += clusterTotalMemoryUsage
datacenter_data['clusters'].append(cluster_data)
datacenterClusterCount += 1
datacenter_data['hosts'] = []
host_property_list = [
"name",
"parent",
"hardware.memorySize",
"hardware.cpuInfo.hz",
"hardware.cpuInfo.numCpuCores",
"hardware.systemInfo.vendor",
"hardware.systemInfo.model",
"hardware.cpuPkg",
"summary.quickStats.overallCpuUsage",
"summary.quickStats.overallMemoryUsage",
"runtime.powerState"
]
host_list = salt.utils.vmware.get_mors_with_properties(
service_instance,
vim.HostSystem,
host_property_list,
container_ref=datacenter['object'],
traversal_spec=None,
)
for host in host_list:
host_data = {}
hostVmCount = 0
if not isinstance(host["parent"], vim.ClusterComputeResource):
host_data['name'] = host['name']
host_data['vender'] = host['hardware.systemInfo.vendor']
host_data['model'] = host['hardware.systemInfo.model']
host_data['powerState'] = host['runtime.powerState']
if host['runtime.powerState'] == 'poweredOn':
overallCpuUsage = host['summary.quickStats.overallCpuUsage']*1000000
overallMemoryUsage = host['summary.quickStats.overallMemoryUsage']*1048576
cpuCapacity = host['hardware.cpuInfo.hz'] * host['hardware.cpuInfo.numCpuCores']
cpuSpace = cpuCapacity - overallCpuUsage
memorySize = host['hardware.memorySize']
memorySpace = host['hardware.memorySize'] - overallMemoryUsage
host_data['cpu_name'] = host['hardware.cpuPkg'][0].description
host_data['cpu_core'] = host['hardware.cpuInfo.numCpuCores']
host_data['cpu_capacity'] = cpuCapacity
host_data['cpu_usage'] = overallCpuUsage
host_data['cpu_space'] = cpuSpace
datacenterTotalCpu += cpuSpace
datacenterTotalCpuUsage += overallCpuUsage
host_data['memory_capacity'] = memorySize
host_data['memory_usage'] = overallMemoryUsage
host_data['memory_space'] = memorySpace
datacenterTotalMemory += memorySpace
datacenterTotalMemoryUsage += overallMemoryUsage
totalDsCapacity = 0
totalFreeSpace = 0
host_datastore_list = get_datastores(service_instance, host['object'])
host_data['datastores'] = []
for hostDsObj in host_datastore_list:
host_datastore_data = {}
host_datastore_data['name'] = hostDsObj['name']
host_datastore_data['capacity'] = hostDsObj['summary.capacity']
host_datastore_data['space'] = hostDsObj['summary.freeSpace']
host_datastore_data['type'] = hostDsObj['summary.type']
host_datastore_data['mode'] = hostDsObj['summary.maintenanceMode']
host_data['datastores'].append(host_datastore_data)
totalDsCapacity += hostDsObj['summary.capacity']
totalFreeSpace += hostDsObj['summary.freeSpace']
host_data['datastores'].append(host_datastore_data)
host_data['storage_capacity'] = totalDsCapacity
host_data['storage_usage'] = totalDsCapacity - totalFreeSpace
host_data['storage_space'] = totalFreeSpace
vm_list = get_vms(service_instance, host['object'])
host_data['vms'] = []
for vm in vm_list:
if vm['summary.config.template'] == False:
vm_data = {}
vm_data['name'] = vm['name']
vm_data['moid'] = vm['object']._moId
vm_data['storage_usage'] = vm['summary.storage.committed']
vm_data['os'] = vm['config.guestFullName']
vm_data['guestId'] = vm['config.guestId']
vm_data['cpu_usage'] = vm['summary.quickStats.overallCpuUsage']*1000000
vm_data['memory_usage'] = vm['summary.quickStats.guestMemoryUsage']*1048576
vm_data['vmPathName'] = vm['config.files.vmPathName']
vm_data['power_state'] = vm['summary.runtime.powerState']
vm_data['memoryMB'] = vm['config.hardware.memoryMB']
vm_data['numCPU'] = vm['config.hardware.numCPU']
if vm['guest.net']:
net = vm['guest.net']
for objNet in net:
if hasattr(objNet.ipConfig, 'ipAddress'):
ipAddress = objNet.ipConfig.ipAddress
for objAddr in ipAddress:
if objAddr.state == 'preferred':
vm_data['ip_address'] = objAddr.ipAddress
host_data['vms'].append(vm_data)
hostVmCount += 1
host_data['vm_count'] = hostVmCount
datacenterVmCount += hostVmCount
datacenter_data['hosts'].append(host_data)
datacenterHostCount += 1
datacenter_data['cpu_space'] = datacenterTotalCpu
datacenter_data['memory_space'] = datacenterTotalMemory
datacenter_data['cpu_usage'] = datacenterTotalCpuUsage
datacenter_data['memory_usage'] = datacenterTotalMemoryUsage
datacenter_data['cluster_count'] = datacenterClusterCount
datacenter_data['host_count'] = datacenterHostCount
datacenter_data['vm_count'] = datacenterVmCount
hw_grain_data['datacenters'].append(datacenter_data)
return hw_grain_data
@depends(HAS_PYVMOMI)
def get_datacenters(service_instance, property_list=None, container_ref=None):
datacenter_list = salt.utils.vmware.get_mors_with_properties(
service_instance,
vim.Datacenter,
property_list,
container_ref=container_ref,
traversal_spec=None,
)
return datacenter_list
@depends(HAS_PYVMOMI)
def get_clusters(service_instance, container_ref=None):
property_list = [
"name",
"summary.totalCpu",
"summary.totalMemory",
"summary.numCpuCores",
"summary.numHosts",
]
cluster_list = salt.utils.vmware.get_mors_with_properties(
service_instance,
vim.ClusterComputeResource,
property_list,
container_ref=container_ref,
traversal_spec=None,
)
return cluster_list
@depends(HAS_PYVMOMI)
def get_hosts(service_instance, container_ref=None):
property_list = [
"name",
"hardware.memorySize",
"hardware.cpuInfo.hz",
"hardware.cpuInfo.numCpuCores",
"hardware.systemInfo.vendor",
"hardware.systemInfo.model",
"hardware.cpuPkg",
"summary.quickStats.overallCpuUsage",
"summary.quickStats.overallMemoryUsage",
"runtime.powerState"
]
traversal_spec = vmodl.query.PropertyCollector.TraversalSpec(
name="cluster_host_traversal",
path="host",
skip=False,
type=vim.ComputeResource,
)
host_list = salt.utils.vmware.get_mors_with_properties(
service_instance,
vim.HostSystem,
property_list,
container_ref=container_ref,
traversal_spec=traversal_spec,
)
return host_list
@depends(HAS_PYVMOMI)
def get_datastores(service_instance, container_ref=None):
property_list = [
"name",
"summary.capacity",
"summary.freeSpace",
"summary.type",
"summary.maintenanceMode"
]
if isinstance(container_ref, vim.HostSystem):
# Create a different traversal spec for hosts because it looks like the
# default doesn't retrieve the datastores
traversal_spec = vmodl.query.PropertyCollector.TraversalSpec(
name="host_datastore_traversal",
path="datastore",
skip=False,
type=vim.HostSystem,
)
elif isinstance(container_ref, vim.ClusterComputeResource):
# Traversal spec for clusters
traversal_spec = vmodl.query.PropertyCollector.TraversalSpec(
name="cluster_datastore_traversal",
path="datastore",
skip=False,
type=vim.ClusterComputeResource,
)
elif isinstance(container_ref, vim.Datacenter):
# Traversal spec for datacenter
traversal_spec = vmodl.query.PropertyCollector.TraversalSpec(
name="datacenter_datastore_traversal",
path="datastore",
skip=False,
type=vim.Datacenter,
)
elif isinstance(container_ref, vim.StoragePod):
# Traversal spec for datastore clusters
traversal_spec = vmodl.query.PropertyCollector.TraversalSpec(
name="datastore_cluster_traversal",
path="childEntity",
skip=False,
type=vim.StoragePod,
)
elif (
isinstance(container_ref, vim.Folder)
and salt.utils.vmware.get_managed_object_name(container_ref) == "Datacenters"
):
# Traversal of root folder (doesn't support multiple levels of Folders)
traversal_spec = vmodl.query.PropertyCollector.TraversalSpec(
path="childEntity",
selectSet=[
vmodl.query.PropertyCollector.TraversalSpec(
path="datastore", skip=False, type=vim.Datacenter
)
],
skip=False,
type=vim.Folder,
)
else:
raise salt.exceptions.ArgumentValueError(
"Unsupported reference type '{0}'" "".format(container_ref.__class__.__name__)
)
datastore_list = salt.utils.vmware.get_mors_with_properties(
service_instance,
vim.Datastore,
property_list,
container_ref=container_ref,
traversal_spec=traversal_spec,
)
return datastore_list
@depends(HAS_PYVMOMI)
def get_vms (service_instance, container_ref):
property_list = [
"name",
"summary.storage.committed",
"summary.config.template",
"summary.quickStats.overallCpuUsage",
"summary.quickStats.guestMemoryUsage",
"summary.runtime.powerState",
"config.guestFullName",
"config.guestId",
"config.files.vmPathName",
"config.hardware.memoryMB",
"config.hardware.numCPU",
"guest.net",
]
traversal_spec = vmodl.query.PropertyCollector.TraversalSpec(
name="host_vm_traversal",
path="vm",
skip=False,
type=vim.HostSystem,
)
vm_list = salt.utils.vmware.get_mors_with_properties(
service_instance,
vim.VirtualMachine,
property_list,
container_ref=container_ref,
traversal_spec=traversal_spec,
)
return vm_list |
Virtual Machine VMRC 접속 Ticket 조회 관련 소스
Code Block | ||
---|---|---|
| ||
@depends(HAS_PYVMOMI)
@ignores_kwargs('credstore')
def get_ticket(host, username, password, protocol=None, port=None):
service_instance = salt.utils.vmware.get_service_instance(host=host,
username=username,
password=password,
protocol=protocol,
port=port)
content = service_instance.RetrieveContent()
session_manager = content.sessionManager
sessionTicket = session_manager.AcquireCloneTicket()
return sessionTicket |
CloudHub addon argument 추가
Add-on features에 대해 VMware Tab on/off optionable
CloudHub server 실행시 argument에 Add-on 옵션추가확인합니다.
Code Block | ||
---|---|---|
| ||
$ esxcli -s <vCenter Server or ESXi host> -u <username> -p <password> -h <host-location> system syslog config get |
Note |
---|
위 명령어를 입력하면 Certificate error. 와 함께 thumbprint : xx:xx:xx:xx:xx … 가 출력 되는데 아래와 같이 thumbprint를 credstore에 추가합니다. |
thumbprint 추가합니다.
Code Block language bash $ /usr/lib/vmware-vcli/apps/general/credstore_admin.pl add --server <host-location> --thumbprint <thumbprint>
Salt vsphere modules 교체
아래 첨부 파일을 python salt modules 경로에 있는 파일과 교체한다.
modules 경로 :
/usr/lib/python3.6/site-packages/salt/modules/vsphere.py
Attachments | ||
---|---|---|
|
Salt-minion 서비스 Python 환경 변수 추가
Code Block | ||
---|---|---|
| ||
$ vim /usr/lib/systemd/system/salt-minion.service
# [Service]에 Python3.6 환경변수 추가
#
Environment="PYTHONPATH=/usr/local/lib/python3.6/site-packages:/usr/lib/python3.6/site-packages"
$ systemctl daemon-reload |
CloudHub Portal addon argument 추가
Sidebar의 Clouds 메뉴에서 VMware Tab을
on/off optionable
처리합니다.CloudHub
argument
에 Add-on 옵션 추가합니다.-u=vsphere:on
Code Block language bash # CloudHub server option #
...
$
...
vim /etc/default
...
/cloudhub CLOUDHUB_OPTS="
...
...
....... -u=vsphere:on \ ......."
CloudHub service 재시작
Code Block language bash $ systemctl daemon-reload $ systemctl restart cloudhub
VMware 탭 show/hide
...
Infrastructure에서 조회된 Host의 Application에 vSphere 가 존재하는지 여부 확인
Note |
---|
VMware 탭이 안보이는 경우
|