Skip to content

Commit 46a26f2

Browse files
committed
Merge branch 'master' of github.com:hpe-container-platform-community/hpecp-python-library
2 parents 3ec2f0c + ea45e0a commit 46a26f2

File tree

8 files changed

+261
-100
lines changed

8 files changed

+261
-100
lines changed

.vscode/settings.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@
2626
],
2727
"python.linting.enabled": true,
2828
"python.formatting.provider": "black",
29-
"python.pythonPath": "/bin/python3",
29+
"python.formatting.blackPath": "/bin/black",
30+
"python.pythonPath": "/usr/bin/python3.5",
3031
"python.envFile": "${workspaceFolder}/gitpod.env",
3132
"editor.formatOnSave": true,
3233
"files.insertFinalNewline": true,
3334
"git.alwaysSignOff": true,
3435
"autoDocstring.docstringFormat": "numpy"
35-
}
36+
}

Dockerfile

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ RUN sudo apt-get update \
66
&& sudo apt-get install -y software-properties-common \
77
&& sudo add-apt-repository -y ppa:deadsnakes/ppa \
88
&& sudo apt-get update \
9-
&& sudo apt-get install -y python3.5 python3.6 python3.7 python3.8 python3.9 tox python3-sphinx vim
9+
&& sudo apt-get install -y python3.5 python3.6 python3.7 python3.8 python3.9 tox python3-sphinx python-pip python3-pip python3.9-distutils vim
1010

11-
RUN pip install -U pylint pytest mock nose flake8-docstrings flake8-per-file-ignores==0.8.1 \
12-
&& pip3 install -U pylint pytest mock nose black flake8-docstrings flake8-per-file-ignores==0.8.1 \
13-
&& pip install -r /tmp/requirements.txt \
14-
&& pip3 install -r /tmp/requirements.txt
11+
# FIXME: Python 3.9 returns errors with pip
12+
RUN echo "Installing python modules" \
13+
&& for v in 2 3 3.5 3.6 3.7 3.8; do python${v} -m pip install -U pylint pytest mock nose flake8-docstrings flake8-per-file-ignores==0.8.1; done \
14+
&& for v in 3 3.5 3.6 3.7 3.8; do python${v} -m pip install -U black; done \
15+
&& sudo ln -s /home/theia/.local/bin//black /bin/ \
16+
&& for v in 2 3 3.5 3.6 3.7 3.8; do python${v} -m pip install -r /tmp/requirements.txt; done
1517

1618
RUN echo 'PATH=$PATH:/home/theia/.local/bin/' >> /home/theia/.bashrc
1719

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99

1010
[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/hpe-container-platform-community/hpecp-python-library)
1111
[![Good first issues open](https://img.shields.io/github/issues/hpe-container-platform-community/hpecp-python-library/good%20first%20issue.svg?label=good%20first%20issue)](https://github.com/hpe-container-platform-community/hpecp-python-library/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
12-
13-
12+
1413

1514
----
1615

@@ -70,6 +69,7 @@ Add gateway:
7069
```sh
7170
hpecp lock create "Install Gateway"
7271
hpecp gateway create-with-ssh-key --ip 10.1.0.5 --proxy-node-hostname my.gateway.local --ssh-key-file controller_private.key
72+
hpecp gateway wait-for-state ${GATEWAY_ID} --states [installed] --timeout-secs 1200
7373
hpecp lock delete-all
7474
```
7575

@@ -132,7 +132,7 @@ hpecp do-something
132132
More sophisticated CLI examples [here](https://github.com/bluedata-community/bluedata-demo-env-aws-terraform/tree/master/bin/experimental)
133133

134134

135-
## Basic Library Usage
135+
## Python Library Examples
136136

137137
See docs: https://hpe-container-platform-community.github.io/hpecp-python-library/index.html
138138

bin/cli.py

Lines changed: 122 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
def intercept_exception(wrapped, instance, args, kwargs):
102102
"""Handle Exceptions.""" # noqa: D202
103103

104-
def _handle_unknown_exception(ex):
104+
def _unknown_exception_handler(ex):
105105
"""Handle unknown exceptions."""
106106
if _log.level == 10: # "DEBUG"
107107
print(
@@ -125,7 +125,7 @@ def _handle_unknown_exception(ex):
125125
print(ae, file=sys.stderr)
126126
sys.exit(1)
127127
except APIUnknownException as ue:
128-
_handle_unknown_exception(ue)
128+
_unknown_exception_handler(ue)
129129
except (
130130
APIException,
131131
APIItemNotFoundException,
@@ -136,7 +136,7 @@ def _handle_unknown_exception(ex):
136136
print(e.message, file=sys.stderr)
137137
sys.exit(1)
138138
except Exception as ex:
139-
_handle_unknown_exception(ex)
139+
_unknown_exception_handler(ex)
140140

141141

142142
@intercept_exception
@@ -181,17 +181,17 @@ def get(self, id, output="yaml", params=None):
181181
self.client, self.client_module_name
182182
)
183183
response = self.client_module_property.get(id=id, params=params)
184+
json_data = response.json
184185

185186
if output == "json":
186-
print(json.dumps(response.json))
187+
print(json.dumps(json_data))
187188
elif output == "json-pp":
188-
print(json.dumps(response.json, indent=4, sort_keys=True,))
189+
print(json.dumps(json_data, indent=4, sort_keys=True,))
189190
else:
191+
190192
print(
191193
yaml.dump(
192-
yaml.load(
193-
json.dumps(response.json), Loader=yaml.FullLoader,
194-
)
194+
yaml.load(json.dumps(json_data), Loader=yaml.FullLoader,)
195195
)
196196
)
197197

@@ -679,7 +679,7 @@ def create_with_ssh_key(
679679
) and wait_for_operation_secs == 0:
680680
print(
681681
(
682-
"if setting disks 'wait-for-operation-secs' parameter"
682+
"If setting disks, 'wait-for-operation-secs' parameter"
683683
" must be greater than zero (recommended 600 seconds)"
684684
),
685685
file=sys.stderr,
@@ -693,10 +693,22 @@ def create_with_ssh_key(
693693
if wait_for_operation_secs > 0:
694694
self.wait_for_status(
695695
id=worker_id,
696-
status=["storage_pending"],
696+
status=["storage_pending", "error"],
697697
timeout_secs=wait_for_operation_secs,
698698
)
699699

700+
if get_client().k8s_worker.get(id=worker_id).status == "error":
701+
print(
702+
(
703+
"Create request has errored. "
704+
"Check status message with `hpecp k8sworker get {}".format(
705+
id
706+
)
707+
),
708+
file=sys.stderr,
709+
)
710+
sys.exit(1)
711+
700712
if ephemeral_disks is not None or persistent_disks is not None:
701713
self.set_storage(
702714
id=worker_id,
@@ -1635,36 +1647,120 @@ def bash(self,):
16351647
cur=${COMP_WORDS[COMP_CWORD]}
16361648
prev=${COMP_WORDS[COMP_CWORD-1]}
16371649
1638-
COMP_WORDS_AS_STRING=$(IFS=. ; echo "${COMP_WORDS[*]}")
1650+
MODULE=${COMP_WORDS[1]}
16391651
1640-
# if the last parameter was --*file
1641-
if echo "${prev}" | grep -q '\-\-.*file$'
1642-
then
1643-
_filedir;
1644-
return
1645-
fi
1652+
COMP_WORDS_AS_STRING=$(IFS=. ; echo "${COMP_WORDS[*]}")
16461653
1654+
# if last input was > for redirecting to a file
1655+
# perform file and directory autocompletion
16471656
if echo "${prev}" | grep -q '>'
16481657
then
16491658
_filedir;
16501659
return
16511660
fi
16521661
1662+
# from: https://stackoverflow.com/a/58221008/1033422
1663+
1664+
declare -A MODULE_COLUMNS=(
1665+
{% for module_name in modules %}
1666+
{% set column_names = " ".join(columns[module_name]) %}
1667+
['{{module_name}}']="{{column_names}}"
1668+
{% endfor %}
1669+
)
1670+
16531671
{% raw %}
1654-
for (( idx=${#COMP_WORDS[@]}-1 ; idx>=0 ; idx-- )) ; do
1655-
item="${COMP_WORDS[idx]}"
1656-
if [[ "${item:0:2}" == "--" ]]; then
1657-
if [[ "${item}" == "--columns" ]]
1672+
# list has uniform behaviour as it is implemented in BaseProxy
1673+
if [[ "${COMP_WORDS[2]}" == "list" ]];
1674+
then
1675+
1676+
# if 'list' was the last word
1677+
if [[ "${prev}" == "list" ]];
1678+
then
1679+
COMPREPLY=( $(compgen -W "--columns --query" -- $cur) )
1680+
return
1681+
fi
1682+
1683+
# FIXME: https://unix.stackexchange.com/questions/124539/bash-completion-for-comma-separated-values
1684+
1685+
# '--columns' was the last word and user is entering column names
1686+
if [[ "${COMP_WORDS[3]}" == "--columns"* && ${#COMP_WORDS[@]} -le 5 ]];
1687+
then
1688+
declare -a COLUMNS=(${MODULE_COLUMNS[$MODULE]})
1689+
1690+
local realcur prefix
1691+
realcur=${cur##*,} # everything after the last comma, e.g. a,b,c,d -> d
1692+
prefix=${cur%,*} # everything before the lat comma, e.g. a,b,c,d -> a,b,c
1693+
1694+
if [[ "$cur" == *,* ]];
16581695
then
1659-
LAST_PARAM_IS_COLUMNS=1
1696+
IFS=',' ENTERED_COLUMNS_LIST=($prefix)
1697+
unset IFS
16601698
else
1661-
LAST_PARAM_IS_COLUMNS=0
1699+
IFS=',' ENTERED_COLUMNS_LIST=($prev)
1700+
unset IFS
1701+
fi
1702+
1703+
for COLUMN in ${COLUMNS[@]}; do
1704+
for ENTERED_COLUMN in ${ENTERED_COLUMNS_LIST[@]}; do
1705+
if [[ "${ENTERED_COLUMN}" == "${COLUMN}" ]]
1706+
then
1707+
# remove columns already entered by user
1708+
COLUMNS=(${COLUMNS[*]//$ENTERED_COLUMN/})
1709+
fi
1710+
done
1711+
done
1712+
1713+
if [[ "$cur" == *,* ]];
1714+
then
1715+
COMPREPLY=( $(compgen -W "${COLUMNS[*]}" -P "${prefix}," -S "," -- ${realcur}) )
1716+
compopt -o nospace
1717+
return
1718+
else
1719+
COMPREPLY=( $(compgen -W "${COLUMNS[*]}" -S "," -- ${realcur}) )
1720+
compopt -o nospace
1721+
return
16621722
fi
1663-
break
16641723
fi
1665-
done
1724+
1725+
# user has finished entering column list or query
1726+
if [[ ${#COMP_WORDS[@]} == 6 ]];
1727+
then
1728+
COMPREPLY=( $(compgen -W "--output" -- $cur) )
1729+
return
1730+
fi
1731+
1732+
if [[ "${COMP_WORDS[5]}" == "--output"* ]];
1733+
then
1734+
if [[ "${COMP_WORDS[3]}" == "--columns"* ]];
1735+
then
1736+
COMPREPLY=( $(compgen -W "table text" -- $cur) )
1737+
return
1738+
else
1739+
COMPREPLY=( $(compgen -W "json json-pp text" -- $cur) )
1740+
return
1741+
fi
1742+
fi
1743+
1744+
return
1745+
fi
16661746
{% endraw %}
16671747
1748+
# if the last parameter was --*file perform
1749+
# file and directory autocompletion
1750+
if echo "${prev}" | grep -q '\-\-.*file$'
1751+
then
1752+
_filedir;
1753+
return
1754+
fi
1755+
1756+
# if last input was > for redirecting to a file
1757+
# perform file and directory autocompletion
1758+
if echo "${prev}" | grep -q '>'
1759+
then
1760+
_filedir;
1761+
return
1762+
fi
1763+
16681764
case "$COMP_WORDS_AS_STRING" in
16691765
16701766
{% set module_names = " ".join(modules.keys()) %}
@@ -1673,27 +1769,7 @@ def bash(self,):
16731769
{% for function_name in modules[module_name] %}
16741770
{% set param_names = " ".join(modules[module_name][function_name]).replace('_', '-') %}
16751771
{% if function_name == "list" %}
1676-
*"hpecp.{{module_name}}.{{function_name.replace('_', '-')}}."*)
1677-
PARAM_NAMES="{{param_names}}"
1678-
for PARAM in ${PARAM_NAMES[@]}; do
1679-
PARAM="${PARAM//'\'}"
1680-
for WORD in ${COMP_WORDS[@]}; do
1681-
if [[ "${WORD}" == "${PARAM}" ]]
1682-
then
1683-
# remove parameters already entered by user
1684-
PARAM_NAMES=${PARAM_NAMES//$WORD/}
1685-
fi
1686-
done
1687-
done
1688-
if [[ $LAST_PARAM_IS_COLUMNS == 1 ]]
1689-
then
1690-
{% set column_names = " ".join(columns[module_name]) %}
1691-
COMPREPLY=( $(compgen -W "{{column_names}}" -- $cur) )
1692-
COMPREPLY+=( $(compgen -W "$PARAM_NAMES" -- $cur) )
1693-
else
1694-
COMPREPLY=( $(compgen -W "$PARAM_NAMES" -- $cur) )
1695-
fi
1696-
;;
1772+
# do nothing - already handled above
16971773
{% else %}
16981774
*"hpecp.{{module_name}}.{{function_name.replace('_', '-')}}."*)
16991775
PARAM_NAMES="{{param_names}}"

hpecp/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
from __future__ import absolute_import
2828

29-
__version__ = "0.5.2"
29+
__version__ = "0.7.1"
3030

3131
from .logger import Logger
3232

hpecp/client.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
import os
2727
from configparser import SafeConfigParser
2828

29+
import logging
2930
import requests
31+
import six
3032
from six import raise_from
3133
from urllib3.exceptions import (
3234
NewConnectionError,
@@ -479,12 +481,22 @@ def create_session(self):
479481

480482
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
481483

484+
if self.log.level == 10: # "DEBUG"
485+
if six.PY3:
486+
import http.client
487+
488+
http.client.HTTPConnection.debuglevel = 1
489+
490+
requests_log = logging.getLogger("requests.packages.urllib3")
491+
requests_log.setLevel(logging.DEBUG)
492+
requests_log.propagate = True
493+
482494
response = None
483495
try:
484496
self.log.debug("REQ: {} : {} {}".format("Login", "post", url))
485497
response = requests.post(
486498
url, json=auth, verify=self.verify_ssl, timeout=10
487-
)
499+
) # 10 seconds
488500
response.raise_for_status()
489501

490502
except (

hpecp/k8s_worker.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,17 +145,18 @@ def create_with_ssh_key(self, ip, ssh_key_data, tags=[]):
145145
url="/api/v2/worker/k8shost/",
146146
http_method="post",
147147
data=data,
148-
description="worker/create_with_ssh_key",
148+
description="K8sWorkerController/create_with_ssh_key",
149149
)
150150
return CaseInsensitiveDict(response.headers)["location"]
151151

152-
def get(self, id, setup_log=False):
152+
def get(self, id, params=None, setup_log=False):
153153

154-
if setup_log is True:
155-
params = {"setup_log": "true"}
156-
else:
154+
if params is None:
157155
params = {}
158156

157+
if setup_log is True:
158+
params["setup_log"] = "true"
159+
159160
return super(K8sWorkerController, self).get(id, params)
160161

161162
def set_storage(self, worker_id, ephemeral_disks=[], persistent_disks=[]):

0 commit comments

Comments
 (0)