def __init__(self, hostname, protocol="https", port=6443, entry='api/v1', **kwargs): self.hostname = hostname self.username = kwargs.get('username', '') self.password = kwargs.get('password', '') self.token = kwargs.get('token', '') self.auth = self.token if self.token else (self.username, self.password) self.api = ContainerClient(hostname, self.auth, protocol, port, entry)
def __init__(self, hostname, protocol="http", port=8080, **kwargs): super(Hawkular, self).__init__(kwargs) self.hostname = hostname self.username = kwargs.get('username', '') self.password = kwargs.get('password', '') self.tenant_id = kwargs.get('tenant_id', 'hawkular') self.auth = self.username, self.password self.inv_api = ContainerClient(hostname, self.auth, protocol, port, "hawkular/inventory") self.alerts_api = ContainerClient(hostname, self.auth, protocol, port, "hawkular/alerts")
class Openshift(Kubernetes): def __init__(self, hostname, protocol="https", port=8443, k_entry="api/v1", o_entry="oapi/v1", **kwargs): self.hostname = hostname self.username = kwargs.get('username', '') self.password = kwargs.get('password', '') self.token = kwargs.get('token', '') self.auth = self.token if self.token else (self.username, self.password) self.k_api = ContainerClient(hostname, self.auth, protocol, port, k_entry) self.o_api = ContainerClient(hostname, self.auth, protocol, port, o_entry) self.api = self.k_api # default api is the kubernetes one for Kubernetes-class requests def list_route(self): """Returns list of routes""" entities = [] entities_j = self.o_api.get('route')[1]['items'] for entity_j in entities_j: meta = entity_j['metadata'] entity = Route(meta['name'], meta['namespace']) entities.append(entity) return entities def list_service(self): """Returns list of services""" entities = [] entities_j = self.api.get('service')[1]['items'] for entity_j in entities_j: meta, spec = entity_j['metadata'], entity_j['spec'] entity = Service( meta['name'], meta['namespace'], spec['portalIP'], spec['sessionAffinity']) entities.append(entity) return entities def list_image_registry(self): """Returns list of image registries (image streams)""" entities = [] entities_j = self.o_api.get('imagestream')[1]['items'] for entity_j in entities_j: reg_raw = entity_j['status']['dockerImageRepository'].split('/')[0] host, port = reg_raw.split(':') if ':' in reg_raw else (reg_raw, '') entity = ImageRegistry(host, port) if entity not in entities: entities.append(entity) return entities def list_project(self): """Returns list of projects""" entities = [] entities_j = self.o_api.get('project')[1]['items'] for entity_j in entities_j: meta = entity_j['metadata'] entity = Project(meta['name']) entities.append(entity) return entities
def __init__(self, hostname, protocol="https", port=8443, k_entry="api/v1", o_entry="oapi/v1", **kwargs): self.hostname = hostname self.username = kwargs.get('username', '') self.password = kwargs.get('password', '') self.token = kwargs.get('token', '') self.auth = self.token if self.token else (self.username, self.password) self.k_api = ContainerClient(hostname, self.auth, protocol, port, k_entry) self.o_api = ContainerClient(hostname, self.auth, protocol, port, o_entry) self.api = self.k_api # default api is the kubernetes one for Kubernetes-class requests
def __init__(self, hostname, protocol="http", port=8080, **kwargs): super(Hawkular, self).__init__(kwargs) self.hostname = hostname self.username = kwargs.get('username', '') self.password = kwargs.get('password', '') self.tenant_id = kwargs.get('tenant_id', 'hawkular') self.auth = self.username, self.password self.inv_api = ContainerClient(hostname, self.auth, protocol, port, "hawkular/inventory") self.alerts_api = ContainerClient(hostname, self.auth, protocol, port, "hawkular/alerts") self.metrics_api = ContainerClient(hostname, self.auth, protocol, port, "hawkular/metrics")
class Hawkular(MgmtSystemAPIBase): """Hawkular management system Hawkular REST API method calls. Will be used by cfme_tests project to verify Hawkular content shown in CFME UI Args: hostname: The Hawkular hostname. protocol: Hawkular REST API protocol. Default value: 'http' port: Hawkular REST API port on provided host. Default value: '8080'. entry: Hawkular REST API entry point URI. Default value: 'hawkular/inventory' username: The username to connect with. password: The password to connect with. """ _stats_available = { 'num_server': lambda self: len(self.list_server()), 'num_deployment': lambda self: len(self.list_server_deployment()), 'num_datasource': lambda self: len(self.list_server_datasource()), } def __init__(self, hostname, protocol="http", port=8080, **kwargs): super(Hawkular, self).__init__(kwargs) self.hostname = hostname self.username = kwargs.get('username', '') self.password = kwargs.get('password', '') self.tenant_id = kwargs.get('tenant_id', 'hawkular') self.auth = self.username, self.password self.inv_api = ContainerClient(hostname, self.auth, protocol, port, "hawkular/inventory") self.alerts_api = ContainerClient(hostname, self.auth, protocol, port, "hawkular/alerts") def _check_inv_version(self, version): return version in self._get_inv_json('status')['Implementation-Version'] def info(self): raise NotImplementedError('info not implemented.') def clone_vm(self, source_name, vm_name): raise NotImplementedError('clone_vm not implemented.') def create_vm(self, vm_name): raise NotImplementedError('create_vm not implemented.') def current_ip_address(self, vm_name): raise NotImplementedError('current_ip_address not implemented.') def delete_vm(self, vm_name): raise NotImplementedError('delete_vm not implemented.') def deploy_template(self, template, *args, **kwargs): raise NotImplementedError('deploy_template not implemented.') def disconnect(self): pass def does_vm_exist(self, name): raise NotImplementedError('does_vm_exist not implemented.') def get_ip_address(self, vm_name): raise NotImplementedError('get_ip_address not implemented.') def is_vm_running(self, vm_name): raise NotImplementedError('is_vm_running not implemented.') def is_vm_stopped(self, vm_name): raise NotImplementedError('is_vm_stopped not implemented.') def is_vm_suspended(self, vm_name): raise NotImplementedError('is_vm_suspended not implemented.') def list_flavor(self): raise NotImplementedError('list_flavor not implemented.') def list_template(self): raise NotImplementedError('list_template not implemented.') def list_vm(self, **kwargs): raise NotImplementedError('list_vm not implemented.') def remove_host_from_cluster(self, hostname): raise NotImplementedError('remove_host_from_cluster not implemented.') def restart_vm(self, vm_name): raise NotImplementedError('restart_vm not implemented.') def start_vm(self, vm_name): raise NotImplementedError('start_vm not implemented.') def stop_vm(self, vm_name): raise NotImplementedError('stop_vm not implemented.') def suspend_vm(self, vm_name): raise NotImplementedError('restart_vm not implemented.') def vm_status(self, vm_name): raise NotImplementedError('vm_status not implemented.') def wait_vm_running(self, vm_name, num_sec): raise NotImplementedError('wait_vm_running not implemented.') def wait_vm_stopped(self, vm_name, num_sec): raise NotImplementedError('wait_vm_stopped not implemented.') def wait_vm_suspended(self, vm_name, num_sec): raise NotImplementedError('wait_vm_suspended not implemented.') def list_server_deployment(self, feed_id=None): """Returns list of server deployments. Possible filters: `feed_id`""" resources = self.list_resource(feed_id=feed_id, resource_type_id='Deployment') deployments = [] if resources: for resource in resources: deployments.append(Deployment(resource.id, resource.name, resource.path)) return deployments def list_server(self, feed_id=None): """Returns list of middleware servers. Possible filters: `feed_id`""" resources = self.list_resource(feed_id=feed_id, resource_type_id='WildFly Server') servers = [] if resources: for resource in resources: resource_data = self.get_config_data( feed_id=resource.path.feed_id, resource_id=resource.id) server_data = resource_data.value servers.append(Server(resource.id, resource.name, resource.path, server_data)) return servers def list_resource(self, resource_type_id, feed_id=None): """Returns list of resources. Possible filters: `feed_id`, `type_id`""" if not feed_id: resources = [] for feed in self.list_feed(): resources.extend(self._list_resource(feed_id=feed.path.feed_id, resource_type_id=resource_type_id)) return resources else: return self._list_resource(feed_id=feed_id, resource_type_id=resource_type_id) def list_child_resource(self, feed_id, resource_id, recursive=False): """Returns list of resources. Possible filters: `feed_id`, `type_id`""" if not feed_id or not resource_id: raise KeyError("'feed_id' and 'resource_id' are a mandatory field!") resources = [] if recursive: entities_j = self._get_inv_json('traversal/f;{}/r;{}/recursive;over=isParentOf;type=r' .format(feed_id, resource_id)) else: entities_j = self._get_inv_json('traversal/f;{}/r;{}/type=r' .format(feed_id, resource_id)) if entities_j: for entity_j in entities_j: resources.append(Resource(entity_j['id'], entity_j['name'], CanonicalPath(entity_j['path']))) return resources def _list_resource(self, feed_id, resource_type_id=None): """Returns list of resources by provided `type_id` and `feed_id`""" if not feed_id: raise KeyError("'feed_id' is a mandatory field!") entities = [] if resource_type_id: entities_j = self._get_inv_json('traversal/f;{}/rt;{}/rl;defines/type=r' .format(feed_id, resource_type_id)) else: entities_j = self._get_inv_json('traversal/f;{}/type=r'.format(feed_id)) if entities_j: for entity_j in entities_j: entities.append(Resource(entity_j['id'], entity_j['name'], CanonicalPath(entity_j['path']))) return entities def get_config_data(self, feed_id, resource_id): """Returns the data/configuration information about resource by provided\ `feed_id` and `resource_id`.""" if not feed_id or not resource_id: raise KeyError("'feed_id' and 'resource_id' are mandatory field!") entity_j = self._get_inv_json('entity/f;{}/r;{}/d;configuration' .format(feed_id, resource_id)) if entity_j: return ResourceData(entity_j['name'], CanonicalPath(entity_j['path']), entity_j['value']) return None def list_feed(self): """Returns list of feeds""" entities = [] entities_j = self._get_inv_json('traversal/type=f') if entities_j: for entity_j in entities_j: entities.append(Feed(entity_j['id'], CanonicalPath(entity_j['path']))) return entities def list_resource_type(self, feed_id): """Returns list of resource types by provided `feed_id`""" if not feed_id: raise KeyError("'feed_id' is a mandatory field!") entities = [] entities_j = self._get_inv_json('traversal/f;{}/type=rt'.format(feed_id)) if entities_j: for entity_j in entities_j: entities.append(ResourceType(entity_j['id'], entity_j['name'], entity_j['path'])) return entities def list_operation_definition(self, feed_id, resource_type_id): if feed_id is None or resource_type_id is None: raise KeyError("'feed_id' and 'resource_type_id' are mandatory fields!") res_j = self._get_inv_json('traversal/f;{}/rt;{}/type=ot'.format(feed_id, resource_type_id)) operations = [] if res_j: for res in res_j: operations.append(OperationType(res['id'], res['name'], CanonicalPath(res['path']))) return operations def list_server_datasource(self, feed_id=None): """Returns list of datasources. Possible filters: `feed_id`""" resources = self.list_resource(feed_id=feed_id, resource_type_id='Datasource') datasources = [] if resources: for resource in resources: datasources.append(Datasource(resource.id, resource.name, resource.path)) return datasources def edit_config_data(self, resource_data, **kwargs): """Edits the data.value information for resource by provided\ `feed_id` and `resource_id`.""" if not isinstance(resource_data, ResourceData) or not resource_data.value: raise KeyError( "'resource_data' should be ResourceData with 'value' attribute") if not kwargs or 'feed_id' not in kwargs or 'resource_id' not in kwargs: raise KeyError("'feed_id' and 'resource_id' are mandatory field!") r = self._put_inv_status('entity/f;{}/r;{}/d;configuration' .format(kwargs['feed_id'], kwargs['resource_id']), {"value": resource_data.value}) return r def create_resource(self, resource, resource_data, resource_type, **kwargs): """Creates new resource and creates it's data by provided\ `feed_id` and `resource_id`.""" if not isinstance(resource, Resource): raise KeyError("'resource' should be an instance of Resource") if not isinstance(resource_data, ResourceData) or not resource_data.value: raise KeyError( "'resource_data' should be ResourceData with 'value' attribute") if not isinstance(resource_type, ResourceType): raise KeyError("'resource_type' should be an instance of ResourceType") if not kwargs or 'feed_id' not in kwargs: raise KeyError('Variable "feed_id" id mandatory field!') resource_id = urlquote(resource.id, safe='') r = self._post_inv_status('entity/f;{}/resource'.format(kwargs['feed_id']), data={"name": resource.name, "id": resource.id, "resourceTypePath": "rt;{}" .format(resource_type.path.resource_type_id)}) if r: r = self._post_inv_status('entity/f;{}/r;{}/data' .format(kwargs['feed_id'], resource_id), data={'role': 'configuration', "value": resource_data.value}) else: # if resource or it's data was not created correctly, delete resource self._delete_inv_status('entity/f;{}/r;{}'.format(kwargs['feed_id'], resource_id)) return r def delete_resource(self, feed_id, resource_id): """Removed the resource by provided `feed_id` and `resource_id`.""" if not feed_id or not resource_id: raise KeyError("'feed_id' and 'resource_id' are mandatory fields!") r = self._delete_inv_status('entity/f;{}/r;{}'.format(feed_id, resource_id)) return r def list_event(self, start_time=0, end_time=sys.maxsize): """Returns the list of events filtered by provided start time and end time. Or lists all events if no argument provided. This information is wrapped into Event.""" entities = [] entities_j = self._get_alerts_json('events?startTime={}&endTime={}' .format(start_time, end_time)) if entities_j: for entity_j in entities_j: entity = Event(entity_j['id'], entity_j['eventType'], entity_j['ctime'], entity_j['dataSource'], entity_j['dataId'], entity_j['category'], entity_j['text']) entities.append(entity) return entities def _get_inv_json(self, path): return self.inv_api.get_json(path, headers={"Hawkular-Tenant": self.tenant_id}) def _post_inv_status(self, path, data): return self.inv_api.post_status(path, data, headers={"Hawkular-Tenant": self.tenant_id, "Content-Type": "application/json"}) def _put_inv_status(self, path, data): return self.inv_api.put_status(path, data, headers={"Hawkular-Tenant": self.tenant_id, "Content-Type": "application/json"}) def _delete_inv_status(self, path): return self.inv_api.delete_status(path, headers={"Hawkular-Tenant": self.tenant_id}) def _get_alerts_json(self, path): return self.alerts_api.get_json(path, headers={"Hawkular-Tenant": self.tenant_id})
class Kubernetes(ContainerMgmtSystemAPIBase): _stats_available = { 'num_container': lambda self: len(self.list_container()), 'num_pod': lambda self: len(self.list_container_group()), 'num_service': lambda self: len(self.list_service()), 'num_replication_controller': lambda self: len(self.list_replication_controller()), 'num_replication_controller_labels': lambda self: len(self.list_replication_controller_labels()), 'num_image': lambda self: len(self.list_image()), 'num_node': lambda self: len(self.list_node()), 'num_image_registry': lambda self: len(self.list_image_registry()), 'num_project': lambda self: len(self.list_project()), } def __init__(self, hostname, protocol="https", port=6443, entry='api/v1', **kwargs): self.hostname = hostname self.username = kwargs.get('username', '') self.password = kwargs.get('password', '') self.token = kwargs.get('token', '') self.auth = self.token if self.token else (self.username, self.password) self.api = ContainerClient(hostname, self.auth, protocol, port, entry) def disconnect(self): pass def _parse_image_info(self, image_str): """Splits full image name into registry, name and tag Both registry and tag are optional, name is always present. Example: localhost:5000/nginx:latest => localhost:5000, nginx, latest """ registry, image_str = image_str.split( '/', 1) if '/' in image_str else ('', image_str) name, tag = image_str.split(':') if ':' in image_str else (image_str, '') return registry, name, tag def info(self): """Returns information about the cluster - number of CPUs and memory in GB""" aggregate_cpu, aggregate_mem = 0, 0 for node in self.list_node(): aggregate_cpu += node.cpu aggregate_mem += node.memory return {'cpu': aggregate_cpu, 'memory': aggregate_mem} def list_container(self): """Returns list of containers (derived from pods)""" entities = [] entities_j = self.api.get('pod')[1]['items'] for entity_j in entities_j: conts_j = entity_j['spec']['containers'] for cont_j in conts_j: cont = Container(cont_j['name'], entity_j['metadata']['name'], cont_j['image']) if cont not in entities: entities.append(cont) return entities def list_container_group(self): """Returns list of container groups (pods)""" entities = [] entities_j = self.api.get('pod')[1]['items'] for entity_j in entities_j: meta, spec = entity_j['metadata'], entity_j['spec'] entity = ContainerGroup(meta['name'], meta['namespace'], spec['restartPolicy'], spec['dnsPolicy']) entities.append(entity) return entities def list_service(self): """Returns list of services""" entities = [] entities_j = self.api.get('service')[1]['items'] for entity_j in entities_j: meta, spec = entity_j['metadata'], entity_j['spec'] entity = Service(meta['name'], meta['namespace'], spec['clusterIP'], spec['sessionAffinity']) entities.append(entity) return entities def list_replication_controller(self): """Returns list of replication controllers""" entities = [] entities_j = self.api.get('replicationcontroller')[1]['items'] for entity_j in entities_j: meta, spec, status = entity_j['metadata'], entity_j[ 'spec'], entity_j['status'] entity = ReplicationController(meta['name'], meta['namespace'], spec['replicas'], status['replicas']) entities.append(entity) return entities def list_replication_controller_label(self): """Returns list of replication controller labels - all objects""" entities = [] entities_j = self.api.get('replicationcontroller')[1]['items'] for entity_j in entities_j: entities.append(entity_j['metadata']['labels']) return entities def list_pod_label(self): """Returns list of pod labels""" entities = [] entities_j = self.api.get('pod')[1]['items'] for entity_j in entities_j: entities.append(entity_j['metadata']['labels']) return entities def list_service_label(self): """Returns list of service labels""" entities = [] entities_j = self.api.get('service')[1]['items'] for entity_j in entities_j: entities.append(entity_j['metadata']['labels']) return entities def list_node_label(self): """Returns list of node labels""" entities = [] entities_j = self.api.get('node')[1]['items'] for entity_j in entities_j: entities.append(entity_j['metadata']['labels']) return entities def list_replication_controller_selector(self): """Returns list of replication controller selectors - rc only""" entities = [] entities_j = self.api.get('replicationcontroller')[1]['items'] for entity_j in entities_j: entities.append(entity_j['spec']['selector']) return entities def list_image(self): """Returns list of images (derived from pods)""" entities = [] entities_j = self.api.get('pod')[1]['items'] for entity_j in entities_j: imgs_j = entity_j['status'].get('containerStatuses', []) for img_j in imgs_j: _, name, tag = self._parse_image_info(img_j['image']) img = Image(name, tag, img_j['imageID']) if img not in entities: entities.append(img) return entities def list_node(self): """Returns list of nodes""" entities = [] entities_j = self.api.get('node')[1]['items'] for entity_j in entities_j: meta, status = entity_j['metadata'], entity_j['status'] cond, cap = status['conditions'][0], status['capacity'] cpu = int(cap['cpu']) memory = int(round(int(cap['memory'][:-2]) * 0.00000102400)) # KiB to GB entity = Node(meta['name'], cond['status'], cpu, memory) entities.append(entity) return entities def list_image_registry(self): """Returns list of image registries (derived from pods)""" entities = [] entities_j = self.api.get('pod')[1]['items'] for entity_j in entities_j: imgs_j = entity_j['status'].get('containerStatuses', []) for img_j in imgs_j: registry, _, _ = self._parse_image_info(img_j['image']) if not registry: continue host, port = registry.split(':') if ':' in registry else ( registry, '') entity = ImageRegistry(host, port) if entity not in entities: entities.append(entity) return entities def list_project(self): """Returns list of projects (namespaces in k8s)""" entities = [] entities_j = self.api.get('namespace')[1]['items'] for entity_j in entities_j: meta = entity_j['metadata'] entity = Project(meta['name']) entities.append(entity) return entities
class Openshift(Kubernetes): def __init__(self, hostname, protocol="https", port=8443, k_entry="api/v1", o_entry="oapi/v1", **kwargs): self.hostname = hostname self.username = kwargs.get('username', '') self.password = kwargs.get('password', '') self.token = kwargs.get('token', '') self.auth = self.token if self.token else (self.username, self.password) self.k_api = ContainerClient(hostname, self.auth, protocol, port, k_entry) self.o_api = ContainerClient(hostname, self.auth, protocol, port, o_entry) self.api = self.k_api # default api is the kubernetes one for Kubernetes-class requests def list_route(self): """Returns list of routes""" entities = [] entities_j = self.o_api.get('route')[1]['items'] for entity_j in entities_j: meta = entity_j['metadata'] entity = Route(meta['name'], meta['namespace']) entities.append(entity) return entities def list_service(self): """Returns list of services""" entities = [] entities_j = self.api.get('service')[1]['items'] for entity_j in entities_j: meta, spec = entity_j['metadata'], entity_j['spec'] entity = Service(meta['name'], meta['namespace'], spec['portalIP'], spec['sessionAffinity']) entities.append(entity) return entities def list_image_registry(self): """Returns list of image registries (image streams)""" entities = [] entities_j = self.o_api.get('imagestream')[1]['items'] for entity_j in entities_j: reg_raw = entity_j['status']['dockerImageRepository'].split('/')[0] host, port = reg_raw.split(':') if ':' in reg_raw else (reg_raw, '') entity = ImageRegistry(host, port) if entity not in entities: entities.append(entity) return entities def list_project(self): """Returns list of projects""" entities = [] entities_j = self.o_api.get('project')[1]['items'] for entity_j in entities_j: meta = entity_j['metadata'] entity = Project(meta['name']) entities.append(entity) return entities
class Kubernetes(ContainerMgmtSystemAPIBase): _stats_available = { 'num_container': lambda self: len(self.list_container()), 'num_pod': lambda self: len(self.list_container_group()), 'num_service': lambda self: len(self.list_service()), 'num_replication_controller': lambda self: len(self.list_replication_controller()), 'num_image': lambda self: len(self.list_image()), 'num_node': lambda self: len(self.list_node()), 'num_image_registry': lambda self: len(self.list_image_registry()), 'num_project': lambda self: len(self.list_project()), } def __init__(self, hostname, protocol="https", port=6443, entry='api/v1', **kwargs): self.hostname = hostname self.username = kwargs.get('username', '') self.password = kwargs.get('password', '') self.token = kwargs.get('token', '') self.auth = self.token if self.token else (self.username, self.password) self.api = ContainerClient(hostname, self.auth, protocol, port, entry) def disconnect(self): pass def _parse_image_info(self, image_str): """Splits full image name into registry, name and tag Both registry and tag are optional, name is always present. Example: localhost:5000/nginx:latest => localhost:5000, nginx, latest """ registry, image_str = image_str.split('/', 1) if '/' in image_str else ('', image_str) name, tag = image_str.split(':') if ':' in image_str else (image_str, '') return registry, name, tag def info(self): """Returns information about the cluster - number of CPUs and memory in GB""" aggregate_cpu, aggregate_mem = 0, 0 for node in self.list_node(): aggregate_cpu += node.cpu aggregate_mem += node.memory return {'cpu': aggregate_cpu, 'memory': aggregate_mem} def list_container(self): """Returns list of containers (derived from pods)""" entities = [] entities_j = self.api.get('pod')[1]['items'] for entity_j in entities_j: conts_j = entity_j['spec']['containers'] for cont_j in conts_j: cont = Container(cont_j['name'], entity_j['metadata']['name'], cont_j['image']) if cont not in entities: entities.append(cont) return entities def list_container_group(self): """Returns list of container groups (pods)""" entities = [] entities_j = self.api.get('pod')[1]['items'] for entity_j in entities_j: meta, spec = entity_j['metadata'], entity_j['spec'] entity = ContainerGroup( meta['name'], meta['namespace'], spec['restartPolicy'], spec['dnsPolicy']) entities.append(entity) return entities def list_service(self): """Returns list of services""" entities = [] entities_j = self.api.get('service')[1]['items'] for entity_j in entities_j: meta, spec = entity_j['metadata'], entity_j['spec'] entity = Service( meta['name'], meta['namespace'], spec['clusterIP'], spec['sessionAffinity']) entities.append(entity) return entities def list_replication_controller(self): """Returns list of replication controllers""" entities = [] entities_j = self.api.get('replicationcontroller')[1]['items'] for entity_j in entities_j: meta, spec, status = entity_j['metadata'], entity_j['spec'], entity_j['status'] entity = ReplicationController( meta['name'], meta['namespace'], spec['replicas'], status['replicas']) entities.append(entity) return entities def list_image(self): """Returns list of images (derived from pods)""" entities = [] entities_j = self.api.get('pod')[1]['items'] for entity_j in entities_j: imgs_j = entity_j['status'].get('containerStatuses', []) for img_j in imgs_j: _, name, tag = self._parse_image_info(img_j['image']) img = Image(name, tag, img_j['imageID']) if img not in entities: entities.append(img) return entities def list_node(self): """Returns list of nodes""" entities = [] entities_j = self.api.get('node')[1]['items'] for entity_j in entities_j: meta, status = entity_j['metadata'], entity_j['status'] cond, cap = status['conditions'][0], status['capacity'] cpu = int(cap['cpu']) memory = int(round(int(cap['memory'][:-2]) * 0.00000102400)) # KiB to GB entity = Node(meta['name'], cond['status'], cpu, memory) entities.append(entity) return entities def list_image_registry(self): """Returns list of image registries (derived from pods)""" entities = [] entities_j = self.api.get('pod')[1]['items'] for entity_j in entities_j: imgs_j = entity_j['status'].get('containerStatuses', []) for img_j in imgs_j: registry, _, _ = self._parse_image_info(img_j['image']) if not registry: continue host, port = registry.split(':') if ':' in registry else (registry, '') entity = ImageRegistry(host, port) if entity not in entities: entities.append(entity) return entities def list_project(self): """Returns list of projects (namespaces in k8s)""" entities = [] entities_j = self.api.get('namespace')[1]['items'] for entity_j in entities_j: meta = entity_j['metadata'] entity = Project(meta['name']) entities.append(entity) return entities
class Hawkular(MgmtSystemAPIBase): """Hawkular management system Hawkular REST API method calls. Will be used by cfme_tests project to verify Hawkular content shown in CFME UI Args: hostname: The Hawkular hostname. protocol: Hawkular REST API protocol. Default value: 'http' port: Hawkular REST API port on provided host. Default value: '8080'. entry: Hawkular REST API entry point URI. Default value: 'hawkular/inventory' username: The username to connect with. password: The password to connect with. """ _stats_available = { 'num_server': lambda self: len(self.list_server()), 'num_domain': lambda self: len(self.list_domain()), 'num_deployment': lambda self: len(self.list_server_deployment()), 'num_datasource': lambda self: len(self.list_server_datasource()), } def __init__(self, hostname, protocol="http", port=8080, **kwargs): super(Hawkular, self).__init__(kwargs) self.hostname = hostname self.username = kwargs.get('username', '') self.password = kwargs.get('password', '') self.tenant_id = kwargs.get('tenant_id', 'hawkular') self.auth = self.username, self.password self.inv_api = ContainerClient(hostname, self.auth, protocol, port, "hawkular/inventory") self.alerts_api = ContainerClient(hostname, self.auth, protocol, port, "hawkular/alerts") self.metrics_api = ContainerClient(hostname, self.auth, protocol, port, "hawkular/metrics") def _check_inv_version(self, version): return version in self._get_inv_json( 'status')['Implementation-Version'] def info(self): raise NotImplementedError('info not implemented.') def clone_vm(self, source_name, vm_name): raise NotImplementedError('clone_vm not implemented.') def create_vm(self, vm_name): raise NotImplementedError('create_vm not implemented.') def current_ip_address(self, vm_name): raise NotImplementedError('current_ip_address not implemented.') def delete_vm(self, vm_name): raise NotImplementedError('delete_vm not implemented.') def deploy_template(self, template, *args, **kwargs): raise NotImplementedError('deploy_template not implemented.') def disconnect(self): pass def does_vm_exist(self, name): raise NotImplementedError('does_vm_exist not implemented.') def get_ip_address(self, vm_name): raise NotImplementedError('get_ip_address not implemented.') def is_vm_running(self, vm_name): raise NotImplementedError('is_vm_running not implemented.') def is_vm_stopped(self, vm_name): raise NotImplementedError('is_vm_stopped not implemented.') def is_vm_suspended(self, vm_name): raise NotImplementedError('is_vm_suspended not implemented.') def list_flavor(self): raise NotImplementedError('list_flavor not implemented.') def list_template(self): raise NotImplementedError('list_template not implemented.') def list_vm(self, **kwargs): raise NotImplementedError('list_vm not implemented.') def remove_host_from_cluster(self, hostname): raise NotImplementedError('remove_host_from_cluster not implemented.') def restart_vm(self, vm_name): raise NotImplementedError('restart_vm not implemented.') def start_vm(self, vm_name): raise NotImplementedError('start_vm not implemented.') def stop_vm(self, vm_name): raise NotImplementedError('stop_vm not implemented.') def suspend_vm(self, vm_name): raise NotImplementedError('restart_vm not implemented.') def vm_status(self, vm_name): raise NotImplementedError('vm_status not implemented.') def wait_vm_running(self, vm_name, num_sec): raise NotImplementedError('wait_vm_running not implemented.') def wait_vm_stopped(self, vm_name, num_sec): raise NotImplementedError('wait_vm_stopped not implemented.') def wait_vm_suspended(self, vm_name, num_sec): raise NotImplementedError('wait_vm_suspended not implemented.') def list_server_deployment(self, feed_id=None): """Returns list of server deployments. Args: feed_id: Feed id of the resource (optional) """ resources = self.list_resource(feed_id=feed_id, resource_type_id='Deployment') deployments = [] if resources: for resource in resources: deployments.append( Deployment(resource.id, resource.name, resource.path)) return deployments def list_server(self, feed_id=None): """Returns list of middleware servers. Args: feed_id: Feed id of the resource (optional) """ resources = self.list_resource(feed_id=feed_id, resource_type_id='WildFly Server') resources.extend( self.list_resource(feed_id=feed_id, resource_type_id='Domain WildFly Server')) servers = [] if resources: for resource in resources: resource_data = self.get_config_data( feed_id=resource.path.feed_id, resource_id=self._get_resource_id( resource.path.resource_id)) server_data = resource_data.value servers.append( Server(resource.id, resource.name, resource.path, server_data)) return servers def list_domain(self, feed_id=None): """Returns list of middleware domains. Args: feed_id: Feed id of the resource (optional) """ resources = self.list_resource(feed_id=feed_id, resource_type_id='Host Controller') domains = [] if resources: for resource in resources: resource_data = self.get_config_data( feed_id=resource.path.feed_id, resource_id=resource.id) domain_data = resource_data.value domains.append( Domain(resource.id, resource.name, resource.path, domain_data)) return domains def list_server_group(self, feed_id): """Returns list of middleware domain's server groups. Args: feed_id: Feed id of the resource (optional) """ resources = self.list_resource(feed_id=feed_id, resource_type_id='Domain Server Group') server_groups = [] if resources: for resource in resources: resource_data = self.get_config_data( feed_id=resource.path.feed_id, resource_id=self._get_resource_id( resource.path.resource_id)) server_group_data = resource_data.value server_groups.append( ServerGroup(resource.id, resource.name, resource.path, server_group_data)) return server_groups def list_resource(self, resource_type_id, feed_id=None): """Returns list of resources. Args: feed_id: Feed id of the resource (optional) resource_type_id: Resource type id """ if not feed_id: resources = [] for feed in self.list_feed(): resources.extend( self._list_resource(feed_id=feed.path.feed_id, resource_type_id=resource_type_id)) return resources else: return self._list_resource(feed_id=feed_id, resource_type_id=resource_type_id) def list_child_resource(self, feed_id, resource_id, recursive=False): """Returns list of resources. Args: feed_id: Feed id of the resource resource_id: Resource id recursive: should be True when you want to get recursively, Default False """ if not feed_id or not resource_id: raise KeyError( "'feed_id' and 'resource_id' are a mandatory field!") resources = [] if recursive: entities_j = self._get_inv_json( 'traversal/f;{}/r;{}/recursive;over=isParentOf;type=r'.format( feed_id, resource_id)) else: entities_j = self._get_inv_json( 'traversal/f;{}/r;{}/type=r'.format(feed_id, resource_id)) if entities_j: for entity_j in entities_j: resources.append( Resource(entity_j['id'], entity_j['name'], CanonicalPath(entity_j['path']))) return resources def _list_resource(self, feed_id, resource_type_id=None): """Returns list of resources. Args: feed_id: Feed id of the resource resource_type_id: Resource type id (optional) """ if not feed_id: raise KeyError("'feed_id' is a mandatory field!") entities = [] if resource_type_id: entities_j = self._get_inv_json( 'traversal/f;{}/rt;{}/rl;defines/type=r'.format( feed_id, resource_type_id)) else: entities_j = self._get_inv_json( 'traversal/f;{}/type=r'.format(feed_id)) if entities_j: for entity_j in entities_j: entities.append( Resource(entity_j['id'], entity_j['name'], CanonicalPath(entity_j['path']))) return entities def get_config_data(self, feed_id, resource_id): """Returns the data/configuration information about resource by provided Args: feed_id: Feed id of the resource resource_id: Resource id """ if not feed_id or not resource_id: raise KeyError("'feed_id' and 'resource_id' are mandatory field!") entity_j = self._get_inv_json( 'entity/f;{}/r;{}/d;configuration'.format( feed_id, self._get_resource_id(resource_id))) if entity_j: return ResourceData(entity_j['name'], CanonicalPath(entity_j['path']), entity_j['value']) return None def list_feed(self): """Returns list of feeds""" entities = [] entities_j = self._get_inv_json('traversal/type=f') if entities_j: for entity_j in entities_j: entities.append( Feed(entity_j['id'], CanonicalPath(entity_j['path']))) return entities def list_resource_type(self, feed_id): """Returns list of resource types. Args: feed_id: Feed id of the resource type """ if not feed_id: raise KeyError("'feed_id' is a mandatory field!") entities = [] entities_j = self._get_inv_json( 'traversal/f;{}/type=rt'.format(feed_id)) if entities_j: for entity_j in entities_j: entities.append( ResourceType(entity_j['id'], entity_j['name'], entity_j['path'])) return entities def list_operation_definition(self, feed_id, resource_type_id): """Lists operations definitions Args: feed_id: Feed id of the operation resource_type_id: Resource type id of the operation """ if feed_id is None or resource_type_id is None: raise KeyError( "'feed_id' and 'resource_type_id' are mandatory fields!") res_j = self._get_inv_json('traversal/f;{}/rt;{}/type=ot'.format( feed_id, resource_type_id)) operations = [] if res_j: for res in res_j: operations.append( OperationType(res['id'], res['name'], CanonicalPath(res['path']))) return operations def list_server_datasource(self, feed_id=None): """Returns list of datasources. Args: feed_id: Feed id of the datasource (optional) """ resources = self.list_resource(feed_id=feed_id, resource_type_id='Datasource') datasources = [] if resources: for resource in resources: datasources.append( Datasource(resource.id, resource.name, resource.path)) return datasources def edit_config_data(self, resource_data, **kwargs): """Edits the data.value information for resource by provided Args: resource_data: Resource data """ if not isinstance(resource_data, ResourceData) or not resource_data.value: raise KeyError( "'resource_data' should be ResourceData with 'value' attribute" ) if not kwargs or 'feed_id' not in kwargs or 'resource_id' not in kwargs: raise KeyError("'feed_id' and 'resource_id' are mandatory field!") r = self._put_inv_status( 'entity/f;{}/r;{}/d;configuration'.format(kwargs['feed_id'], kwargs['resource_id']), {"value": resource_data.value}) return r def create_resource(self, resource, resource_data, resource_type, **kwargs): """Creates new resource and creates it's data by provided Args: resource: resource kwargs: feed_id, resource_id and required fields resource_data: Resource data resource_type: Resource type """ if not isinstance(resource, Resource): raise KeyError("'resource' should be an instance of Resource") if not isinstance(resource_data, ResourceData) or not resource_data.value: raise KeyError( "'resource_data' should be ResourceData with 'value' attribute" ) if not isinstance(resource_type, ResourceType): raise KeyError( "'resource_type' should be an instance of ResourceType") if not kwargs or 'feed_id' not in kwargs: raise KeyError('Variable "feed_id" id mandatory field!') resource_id = urlquote(resource.id, safe='') r = self._post_inv_status( 'entity/f;{}/resource'.format(kwargs['feed_id']), data={ "name": resource.name, "id": resource.id, "resourceTypePath": "rt;{}".format(resource_type.path.resource_type_id) }) if r: r = self._post_inv_status('entity/f;{}/r;{}/data'.format( kwargs['feed_id'], resource_id), data={ 'role': 'configuration', "value": resource_data.value }) else: # if resource or it's data was not created correctly, delete resource self._delete_inv_status('entity/f;{}/r;{}'.format( kwargs['feed_id'], resource_id)) return r def delete_resource(self, feed_id, resource_id): """Removed a resource. Args: feed_id: Feed id of the data source resource_id: Resource id of the datasource """ if not feed_id or not resource_id: raise KeyError("'feed_id' and 'resource_id' are mandatory fields!") r = self._delete_inv_status('entity/f;{}/r;{}'.format( feed_id, resource_id)) return r def list_event(self, start_time=0, end_time=sys.maxsize): """Returns the list of events. Filtered by provided start time and end time. Or lists all events if no argument provided. This information is wrapped into Event. Args: start_time: Start time as timestamp end_time: End time as timestamp """ entities = [] entities_j = self._get_alerts_json( 'events?startTime={}&endTime={}'.format(start_time, end_time)) if entities_j: for entity_j in entities_j: entity = Event(entity_j['id'], entity_j['eventType'], entity_j['ctime'], entity_j['dataSource'], entity_j['dataId'], entity_j['category'], entity_j['text']) entities.append(entity) return entities def _get_inv_json(self, path): return self.inv_api.get_json( path, headers={"Hawkular-Tenant": self.tenant_id}) def _post_inv_status(self, path, data): return self.inv_api.post_status(path, data, headers={ "Hawkular-Tenant": self.tenant_id, "Content-Type": "application/json" }) def _put_inv_status(self, path, data): return self.inv_api.put_status(path, data, headers={ "Hawkular-Tenant": self.tenant_id, "Content-Type": "application/json" }) def _delete_inv_status(self, path): return self.inv_api.delete_status( path, headers={"Hawkular-Tenant": self.tenant_id}) def _get_alerts_json(self, path): return self.alerts_api.get_json( path, headers={"Hawkular-Tenant": self.tenant_id}) def _get_metrics_json(self, path, params=None): return self.metrics_api.get_json( path, headers={"Hawkular-Tenant": self.tenant_id}, params=params) def _get_resource_id(self, resource_id): if isinstance(resource_id, list): return "{}".format('/r;'.join(resource_id)) else: return resource_id def status_alerts(self): """returns status of alerts service""" return self._get_alerts_json(path='status') def status_inventory(self): """Returns status of inventory service""" return self._get_inv_json(path='status') def status_metrics(self): """Returns status of metrics service""" return self._get_metrics_json(path='status') def status(self): """Returns status of alerts, inventory and metrics services""" return { 'alerts': self.status_alerts(), 'inventory': self.status_inventory(), 'metrics': self.status_metric() } def list_metric_availability_feed(self, feed_id, **kwargs): """Returns list of DataPoint of a feed Args: feed_id: Feed id of the metric resource kwargs: Refer ``list_metric_availability`` """ metric_id = "hawkular-feed-availability-{}".format(feed_id) return self.list_metric_availability(metric_id=metric_id, **kwargs) def list_metric_availability_server(self, feed_id, server_id, **kwargs): """Returns list of `DataPoint` of a server Args: feed_id: Feed id of the server server_id: Server id kwargs: Refer ``list_metric_availability`` """ metric_id = "AI~R~[{}/{}~~]~AT~Server Availability~Server Availability" \ .format(feed_id, server_id) return self.list_metric_availability(metric_id=metric_id, **kwargs) def list_metric_availability_deployment(self, feed_id, server_id, resource_id, **kwargs): """Returns list of `DataPoint` of a deployment Args: feed_id: Feed id of the deployment server_id: Server id of the deployment resource_id: deployment id kwargs: Refer ``list_metric_availability`` """ metric_id = "AI~R~[{}/{}~/deployment={}]~AT~Deployment Status~Deployment Status" \ .format(feed_id, server_id, resource_id) return self.list_metric_availability(metric_id=metric_id, **kwargs) def list_metric_availability(self, metric_id, **kwargs): """Returns list of `DataPoint` of a metric Args: metric_id: Metric id kwargs: refer optional query params and query type Optional query params: start: timestamp, Defaults to now: 8 hours end: timestamp, Defaults to now buckets: Total number of buckets bucketDuration: Bucket duration distinct: Set to true to return only distinct, contiguous values limit: Limit the number of data points returned order: Data point sort order, based on timestamp [values: ASC, DESC] Query type: raw: set True when you want to get raw data, Default False which returns stats """ prefix_id = "availability/{}".format(urlquote(metric_id, safe='')) return self._list_metric_data(prefix_id=prefix_id, **kwargs) def list_metric_gauge_datasource(self, feed_id, server_id, resource_id, metric_enum, **kwargs): """Returns list of NumericBucketPoint of datasource metric Args: feed_id: feed id of the datasource server_id: server id of the datasource resource_id: resource id, here which is datasource id metric_enum: Any one of *DS_* Enum value from ``MetricEnumGauge`` kwargs: Refer ``list_metric_gauge`` """ if not isinstance(metric_enum, MetricEnumGauge): raise KeyError( "'metric_enum' should be a type of 'MetricEnumGauge' Enum class" ) return self._list_metric_gauge_datasource( feed_id=feed_id, server_id=server_id, resource_id=resource_id, metric_type=metric_enum.metric_type, metric_sub_type=metric_enum.sub_type, **kwargs) def _list_metric_gauge_datasource(self, feed_id, server_id, resource_id, metric_type, metric_sub_type, **kwargs): metric_id = "MI~R~[{}/{}~/subsystem=datasources/data-source={}]~MT~{}~{}" \ .format(feed_id, server_id, resource_id, metric_type, metric_sub_type) return self.list_metric_gauge(metric_id=metric_id, **kwargs) def list_metric_gauge_server(self, feed_id, server_id, metric_enum, **kwargs): """Returns list of `NumericBucketPoint` of server metric Args: feed_id: feed id of the server server_id: server id metric_enum: Any one of *SVR_* ``Enum`` value from ``MetricEnumGauge`` kwargs: Refer ``list_metric_gauge`` """ if not isinstance(metric_enum, MetricEnumGauge): raise KeyError( "'metric_enum' should be a type of 'MetricEnumGauge' Enum class" ) return self._list_metric_gauge_server( feed_id=feed_id, server_id=server_id, metric_type=metric_enum.metric_type, metric_sub_type=metric_enum.sub_type, **kwargs) def _list_metric_gauge_server(self, feed_id, server_id, metric_type, metric_sub_type, **kwargs): metric_id = "MI~R~[{}/{}~~]~MT~{}~{}".format(feed_id, server_id, metric_type, metric_sub_type) return self.list_metric_gauge(metric_id=metric_id, **kwargs) def list_metric_gauge(self, metric_id, **kwargs): """Returns list of `NumericBucketPoint` of a metric Args: metric_id: Metric id kwargs: Refer optional query params and query type Optional query params: start: timestamp, Defaults to now: 8 hours end: timestamp, Defaults to now buckets: Total number of buckets bucketDuration: Bucket duration distinct: Set to true to return only distinct, contiguous values limit: Limit the number of data points returned order: Data point sort order, based on timestamp [values: ASC, DESC] Query type: raw: set True when you want to get raw data, Default False which returns stats rate: set True when you want rate data default False stats: return stats data default True """ prefix_id = "gauges/{}".format(urlquote(metric_id, safe='')) return self._list_metric_data(prefix_id=prefix_id, **kwargs) def list_metric_counter_server(self, feed_id, server_id, metric_enum, **kwargs): """Returns list of `NumericBucketPoint` of server metric Args: feed_id: feed id of the server server_id: server id metric_enum: Any one of *SVR_* ``Enum`` value from ``MetricEnumCounter`` kwargs: Refer ``list_metric_counter`` """ if not isinstance(metric_enum, MetricEnumCounter): raise KeyError( "'metric_enum' should be a type of 'MetricEnumCounter' Enum class" ) return self._list_metric_counter_server( feed_id=feed_id, server_id=server_id, metric_type=metric_enum.metric_type, metric_sub_type=metric_enum.sub_type, **kwargs) def _list_metric_counter_server(self, feed_id, server_id, metric_type, metric_sub_type, **kwargs): if MetricEnumCounter.SVR_TXN_NUMBER_OF_TRANSACTIONS.metric_type == metric_type: metric_id = "MI~R~[{}/{}~/subsystem=transactions]~MT~{}~{}"\ .format(feed_id, server_id, metric_type, metric_sub_type) else: metric_id = "MI~R~[{}/{}~~]~MT~{}~{}".format( feed_id, server_id, metric_type, metric_sub_type) return self.list_metric_counter(metric_id=metric_id, **kwargs) def list_metric_counter_deployment(self, feed_id, server_id, resource_id, metric_enum, **kwargs): """Returns list of `NumericBucketPoint` of server metric Args: feed_id: feed id of the deployment server_id: server id of the deployment resource_id: resource id, that's deployment id metric_enum: Any one of *DEP_* ``Enum`` value from ``MetricEnumCounter`` kwargs: Refer ``list_metric_counter`` """ if not isinstance(metric_enum, MetricEnumCounter): raise KeyError( "'metric_enum' should be a type of 'MetricEnumCounter' Enum class" ) return self._list_metric_counter_deployment( feed_id=feed_id, server_id=server_id, resource_id=resource_id, metric_type=metric_enum.metric_type, metric_sub_type=metric_enum.sub_type, **kwargs) def _list_metric_counter_deployment(self, feed_id, server_id, resource_id, metric_type, metric_sub_type, **kwargs): metric_id = "MI~R~[{}/{}~/deployment={}]~MT~{}~{}"\ .format(feed_id, server_id, resource_id, metric_type, metric_sub_type) return self.list_metric_counter(metric_id=metric_id, **kwargs) def list_metric_counter(self, metric_id, **kwargs): """Returns list of `NumericBucketPoint` of a metric Args: metric_id: metric id kwargs: Refer optional query params and query type Optional query params: start: timestamp, Defaults to now: 8 hours end: timestamp, Defaults to now buckets: Total number of buckets bucketDuration: Bucket duration distinct: Set to true to return only distinct, contiguous values limit: Limit the number of data points returned order: Data point sort order, based on timestamp [values: ASC, DESC] Query type: raw: set True when you want to get raw data, Default False which returns stats rate: set True when you want rate data default False stats: return stats data default True """ prefix_id = "counters/{}".format(urlquote(metric_id, safe='')) return self._list_metric_data(prefix_id=prefix_id, **kwargs) def list_metric_availability_definition(self): """Lists all availability type metric definitions""" return self._get_metrics_json(path='availability') def list_metric_gauge_definition(self): """Lists all gauge type metric definitions""" return self._get_metrics_json(path='gauges') def list_metric_counter_definition(self): """Lists all counter type metric definitions""" return self._get_metrics_json(path='counters') def list_metric_definition(self): """Lists all metric definitions""" return self._get_metrics_json(path='metrics') def _list_metric_data(self, prefix_id, **kwargs): params = { 'start': kwargs.get('start', None), 'end': kwargs.get('end', None), 'bucketDuration': kwargs.get('bucketDuration', None), 'buckets': kwargs.get('buckets', None), 'percentiles': kwargs.get('percentiles', None), 'limit': kwargs.get('limit', None), 'order': kwargs.get('order', None), } raw = kwargs.get('raw', False) rate = kwargs.get('rate', False) if not raw and params['bucketDuration'] is None and params[ 'buckets'] is None: raise KeyError( "Either the 'buckets' or 'bucketDuration' parameter must be used" ) if rate: return self._get_metrics_json( path='{}/rate/stats'.format(prefix_id), params=params) elif raw: return self._get_metrics_json(path='{}/raw'.format(prefix_id), params=params) else: return self._get_metrics_json(path='{}/stats'.format(prefix_id), params=params)