Source code for hpecp.gateway

# (C) Copyright [2020] Hewlett Packard Enterprise Development LP
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.

from __future__ import absolute_import

from enum import Enum

from requests.structures import CaseInsensitiveDict

from hpecp.base_resource import ResourceList

from .base_resource import AbstractResource, AbstractWaitableResourceController
from .exceptions import APIItemNotFoundException

try:
    basestring
except NameError:
    basestring = str


[docs]class GatewayStatus(Enum): """Bases: enum.Enum The statuses for a Gateway **Note:** The integer values do not have a meaning outside of this library. The API uses a string identifier with the status name rather than an integer value. """ bundle = 1 installing = 2 installed = 3 ready = 4 unlicensed = 5 configuring = 6 configured = 7 error = 8 sysinfo = 9 unconfiguring = 10 deleting = 11 storage_pending = 12 storage_configuring = 13 storage_error = 14 decommission_in_progress = 15 delete_in_progress = 16
[docs]class Gateway(AbstractResource): """Create an instance of Gateway from json data returned from the HPE Container Platform API. Users of this library are not expected to create an instance of this class. Parameters ---------- json : str The json returned by the API representing a Gateway. Returns ------- Gateway An instance of Gateway """ # All of the fields of Gateway objects as returned by the HPE Container # Platform API all_fields = [ "id", "hacapable", "propinfo", "approved_worker_pubkey", "schedule", "ip", "proxy_nodes_hostname", "hostname", "state", "status_info", "purpose", "sysinfo", "tags", ] # These fields are displayed by default, e.g. in tabulate() default_display_fields = [ "id", "ip", "proxy_nodes_hostname", "hostname", "state", "status_info", "purpose", "tags", ] @property def state(self): """@Field: from json['state']""" return self.json["state"] @property def hacapable(self): """@Field: from json['hacapable']""" return self.json["hacapable"] @property def propinfo(self): """@Field: from json['propinfo']""" return self.json["propinfo"] @property def approved_worker_pubkey(self): """@Field: from json['approved_worker_pubkey']""" return self.json["approved_worker_pubkey"] @property def schedule(self): """@Field: from json['schedule']""" return self.json["schedule"] @property def ip(self): """@Field: from json['ip']""" return self.json["ip"] @property def proxy_nodes_hostname(self): """@Field: from json['proxy_nodes_hostname']""" try: return self.json["proxy_nodes_hostname"] except KeyError: return "" @property def hostname(self): """@Field: from json['hostname']""" return self.json["hostname"] @property def purpose(self): """@Field: from json['purpose']""" return self.json["purpose"] @property def status_info(self): """@Field: from json['status_info']""" return self.json["status_info"] @property def sysinfo(self): """@Field: from json['sysinfo']""" return self.json["sysinfo"] @property def tags(self): """@Field: from json['tags']""" return self.json["tags"]
[docs]class GatewayController(AbstractWaitableResourceController): """Class that users will interact with to work with Gateways. An instance of this class is available in the client.ContainerPlatformClient with the attribute name :py:attr:`gateway <.client.ContainerPlatformClient.gateway>`. The methods of this class can be invoked using `client.gateway.method()`. See the example below: Example ------- >>> client = ContainerPlatformClient(...).create_session() >>> client.gateway.list() """ base_resource_path = "/api/v1/workers" resource_list_path = "workers" resource_class = Gateway status_class = GatewayStatus status_fieldname = "state" # def create_with_ssh_password(self, username, password): # """Not Implemented yet""" # raise NotImplementedError()
[docs] def create_with_ssh_key( self, ip, proxy_node_hostname, ssh_key_data, ssh_passphrase=None, tags=[], ): """Create a gateway instance using SSH key credentials to access the host. Parameters ---------- ip: str The IP address of the proxy host. Used for internal communication. proxy_node_hostname: str Clients will access cluster services will be accessed using this name. ssh_key_data: str The ssh key data as a string. ssh_passphrase: str The ssh passphrase tags: list Tags to use, e.g. "{ 'tag1': 'foo', 'tag2', 'bar' }". Returns ------- str gateway ID """ assert isinstance( ip, basestring ), "'ip' must be provided and must be a string" assert isinstance( proxy_node_hostname, basestring ), "'proxy_node_hostname' must be provided and must be a string" assert isinstance( ssh_key_data, basestring ), "'ssh_key_data' must be provided and must be a string" data = { "ip": ip, "credentials": { "type": "ssh_key_access", "ssh_key_data": ssh_key_data, }, "tags": tags, "proxy_nodes_hostname": proxy_node_hostname, "purpose": "proxy", } if ssh_passphrase is not None: data["credentials"]["ssh_key_passphrase"] = ssh_passphrase response = self.client._request( url="/api/v1/workers/", http_method="post", data=data, description="gateway/create_with_ssh_key", ) return CaseInsensitiveDict(response.headers)["location"]
[docs] def get(self, id): """Retrieve a Gateway by ID. Parameters ---------- id: str The gateway ID - format: '/api/v1/workers/[0-9]+' Returns ------- Gateway object representing a Gateway Raises ------ APIException """ worker = super(GatewayController, self).get(id) if worker.purpose != "proxy": raise APIItemNotFoundException( message="gateway not found with id: " + id, request_method="get", request_url=id, ) return worker
[docs] def list(self): """Make an API call to retrieve a list of Resources. Returns ------- ResourceList The ResourceList will contain instances of the class defined by the property self.resource_class """ resourceList = super(GatewayController, self).list() gateways = [gw for gw in resourceList.json if gw["purpose"] == "proxy"] return ResourceList(self.resource_class, gateways)
# TODO refactor clients so implementation not required
[docs] def wait_for_state(self, gateway_id, state=[], timeout_secs=1200): return super(GatewayController, self).wait_for_state( gateway_id, state, timeout_secs )