Tanvir Talukder e30684b0c3 Valet Documentation
Added REST API Documentation
Added Valet Plugins Documentation
Added Apache License info
2017-05-01 19:07:42 -05:00

346 lines
11 KiB
Python
Executable File

# 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.
# Modified: Sep. 27, 2016
from novaclient import client as nova_client
from oslo_config import cfg
from resource_base import Host, LogicalGroup, Flavor
import traceback
# Nova API v2
VERSION = 2
CONF = cfg.CONF
class Compute(object):
def __init__(self, _logger):
self.logger = _logger
self.nova = None
def set_hosts(self, _hosts, _logical_groups):
self._get_nova_client()
status = self._set_availability_zones(_hosts, _logical_groups)
if status != "success":
self.logger.error('_set_availability_zones failed')
return status
status = self._set_aggregates(_hosts, _logical_groups)
if status != "success":
self.logger.error('_set_aggregates failed')
return status
status = self._set_placed_vms(_hosts, _logical_groups)
if status != "success":
self.logger.error('_set_placed_vms failed')
return status
status = self._set_resources(_hosts)
if status != "success":
self.logger.error('_set_resources failed')
return status
return "success"
def _get_nova_client(self):
'''Returns a nova client'''
self.nova = nova_client.Client(VERSION,
CONF.identity.username,
CONF.identity.password,
CONF.identity.project_name,
CONF.identity.auth_url)
def _set_availability_zones(self, _hosts, _logical_groups):
try:
hosts_list = self.nova.hosts.list()
try:
for h in hosts_list:
if h.service == "compute":
host = Host(h.host_name)
host.tag.append("nova")
logical_group = None
if h.zone not in _logical_groups.keys():
logical_group = LogicalGroup(h.zone)
logical_group.group_type = "AZ"
_logical_groups[logical_group.name] = logical_group
else:
logical_group = _logical_groups[h.zone]
host.memberships[logical_group.name] = logical_group
if host.name not in logical_group.vms_per_host.keys():
logical_group.vms_per_host[host.name] = []
self.logger.info("adding Host LogicalGroup: " + str(host.__dict__))
_hosts[host.name] = host
except (ValueError, KeyError, TypeError):
self.logger.error(traceback.format_exc())
return "Error while setting host zones from Nova"
except Exception:
self.logger.critical(traceback.format_exc())
return "success"
def _set_aggregates(self, _hosts, _logical_groups):
aggregate_list = self.nova.aggregates.list()
try:
for a in aggregate_list:
aggregate = LogicalGroup(a.name)
aggregate.group_type = "AGGR"
if a.deleted is not False:
aggregate.status = "disabled"
metadata = {}
for mk in a.metadata.keys():
metadata[mk] = a.metadata.get(mk)
aggregate.metadata = metadata
self.logger.info("adding aggregate LogicalGroup: " + str(aggregate.__dict__))
_logical_groups[aggregate.name] = aggregate
for hn in a.hosts:
host = _hosts[hn]
host.memberships[aggregate.name] = aggregate
aggregate.vms_per_host[host.name] = []
except (ValueError, KeyError, TypeError):
self.logger.error(traceback.format_exc())
return "Error while setting host aggregates from Nova"
return "success"
# NOTE: do not set any info in _logical_groups
def _set_placed_vms(self, _hosts, _logical_groups):
error_status = None
for hk in _hosts.keys():
vm_uuid_list = []
result_status = self._get_vms_of_host(hk, vm_uuid_list)
if result_status == "success":
for vm_uuid in vm_uuid_list:
vm_detail = [] # (vm_name, az, metadata, status)
result_status_detail = self._get_vm_detail(vm_uuid, vm_detail)
if result_status_detail == "success":
# if vm_detail[3] != "SHUTOFF": # status == "ACTIVE" or "SUSPENDED"
vm_id = ("none", vm_detail[0], vm_uuid)
_hosts[hk].vm_list.append(vm_id)
# _logical_groups[vm_detail[1]].vm_list.append(vm_id)
# _logical_groups[vm_detail[1]].vms_per_host[hk].append(vm_id)
else:
error_status = result_status_detail
break
else:
error_status = result_status
if error_status is not None:
break
if error_status is None:
return "success"
else:
return error_status
def _get_vms_of_host(self, _hk, _vm_list):
hypervisor_list = self.nova.hypervisors.search(hypervisor_match=_hk, servers=True)
try:
for hv in hypervisor_list:
if hasattr(hv, 'servers'):
server_list = hv.__getattr__('servers')
for s in server_list:
_vm_list.append(s.uuid)
except (ValueError, KeyError, TypeError):
self.logger.error(traceback.format_exc())
return "Error while getting existing vms"
return "success"
def _get_vm_detail(self, _vm_uuid, _vm_detail):
server = self.nova.servers.get(_vm_uuid)
try:
vm_name = server.name
_vm_detail.append(vm_name)
az = server.__getattr("OS-EXT-AZ:availability_zone")
_vm_detail.append(az)
metadata = server.metadata
_vm_detail.append(metadata)
status = server.status
_vm_detail.append(status)
except (ValueError, KeyError, TypeError):
self.logger.error(traceback.format_exc())
return "Error while getting vm detail"
return "success"
def _set_resources(self, _hosts):
# Returns Hypervisor list
host_list = self.nova.hypervisors.list()
try:
for hv in host_list:
if hv.service['host'] in _hosts.keys():
host = _hosts[hv.service['host']]
host.status = hv.status
host.state = hv.state
host.original_vCPUs = float(hv.vcpus)
host.vCPUs_used = float(hv.vcpus_used)
host.original_mem_cap = float(hv.memory_mb)
host.free_mem_mb = float(hv.free_ram_mb)
host.original_local_disk_cap = float(hv.local_gb)
host.free_disk_gb = float(hv.free_disk_gb)
host.disk_available_least = float(hv.disk_available_least)
except (ValueError, KeyError, TypeError):
self.logger.error(traceback.format_exc())
return "Error while setting host resources from Nova"
return "success"
def set_flavors(self, _flavors):
error_status = None
self._get_nova_client()
result_status = self._set_flavors(_flavors)
if result_status == "success":
for _, f in _flavors.iteritems():
result_status_detail = self._set_extra_specs(f)
if result_status_detail != "success":
error_status = result_status_detail
break
else:
error_status = result_status
if error_status is None:
return "success"
else:
return error_status
def _set_flavors(self, _flavors):
# Get a list of all flavors
flavor_list = self.nova.flavors.list()
try:
for f in flavor_list:
flavor = Flavor(f.name)
flavor.flavor_id = f.id
if hasattr(f, "OS-FLV-DISABLED:disabled"):
if getattr(f, "OS-FLV-DISABLED:disabled"):
flavor.status = "disabled"
flavor.vCPUs = float(f.vcpus)
flavor.mem_cap = float(f.ram)
root_gb = float(f.disk)
ephemeral_gb = 0.0
if hasattr(f, "OS-FLV-EXT-DATA:ephemeral"):
ephemeral_gb = float(getattr(f, "OS-FLV-EXT-DATA:ephemeral"))
swap_mb = 0.0
if hasattr(f, "swap"):
sw = getattr(f, "swap")
if sw != '':
swap_mb = float(sw)
flavor.disk_cap = root_gb + ephemeral_gb + swap_mb / float(1024)
self.logger.info("adding flavor " + str(flavor.__dict__))
_flavors[flavor.name] = flavor
except (ValueError, KeyError, TypeError):
self.logger.error(traceback.format_exc())
return "Error while getting flavors"
return "success"
def _set_extra_specs(self, _flavor):
try:
# Get a list of all flavors
flavors_list = self.nova.flavors.list()
# Get flavor from flavor_list
for flavor in flavors_list:
if flavor.id == _flavor.flavor_id:
extra_specs = flavor.get_keys()
for sk, sv in extra_specs.iteritems():
_flavor.extra_specs[sk] = sv
break
except (ValueError, KeyError, TypeError):
self.logger.error(traceback.format_exc())
return "Error while getting flavor extra spec"
return "success"
# Unit test
'''
if __name__ == '__main__':
config = Config()
config_status = config.configure()
if config_status != "success":
print "Error while configuring Ostro: " + config_status
sys.exit(2)
auth = Authentication()
admin_token = auth.get_tenant_token(config)
if admin_token is None:
print "Error while getting admin_token"
sys.exit(2)
else:
print "admin_token=",admin_token
project_token = auth.get_project_token(config, admin_token)
if project_token is None:
print "Error while getting project_token"
sys.exit(2)
else:
print "project_token=",project_token
c = Compute(config, admin_token, project_token)
hosts = {}
logical_groups = {}
flavors = {}
#c._set_availability_zones(hosts, logical_groups)
#c._set_aggregates(None, logical_groups)
#c._set_placed_vms(hosts, logical_groups)
#c._get_vms_of_host("qos101", None)
#c._get_vm_detail("20b2890b-81bb-4942-94bf-c6bee29630bb", None)
c._set_resources(hosts)
#c._set_flavors(flavors)
'''