Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 9a6ffc39 authored by SIMONIN Matthieu's avatar SIMONIN Matthieu
Browse files

Merge branch 'fix_ssl' into 'master'

Improve SSL user experience on Grid'5000

See merge request !7
parents 9e7bd874 e7de8a20
No related branches found
No related tags found
1 merge request!7Improve SSL user experience on Grid'5000
Pipeline #519825 failed
...@@ -83,9 +83,10 @@ password: MYPASSWORD ...@@ -83,9 +83,10 @@ password: MYPASSWORD
' > ~/.python-grid5000.yaml ' > ~/.python-grid5000.yaml
#+END_EXAMPLE #+END_EXAMPLE
- When accessing the API from a Grid'5000 frontend, providing the username and - When accessing the API from a Grid'5000 frontend, providing the username
password is optionnal. Nevertheless you'll need to deal with SSL verification and password is optionnal. Authentication should work out-of-the-box; if
by specifying the path to the certificate to use: it fails, try updating python-grid5000, or specify the path to the
certificate to use:
#+BEGIN_EXAMPLE #+BEGIN_EXAMPLE
echo ' echo '
......
...@@ -88,9 +88,10 @@ conform with the Grid5000 API models (with an ’s’!) ...@@ -88,9 +88,10 @@ conform with the Grid5000 API models (with an ’s’!)
password: MYPASSWORD password: MYPASSWORD
' > ~/.python-grid5000.yaml ' > ~/.python-grid5000.yaml
- When accessing the API from a Grid’5000 frontend, providing the username and - When accessing the API from a Grid’5000 frontend, providing the username
password is optionnal. Nevertheless you’ll need to deal with SSL verification and password is optionnal. Authentication should work out-of-the-box; if
by specifying the path to the certificate to use: it fails, try updating python-grid5000, or specify the path to the
certificate to use:
:: ::
...@@ -614,51 +615,7 @@ connected to other testbeds for experiments involving wide area layer2 networks. ...@@ -614,51 +615,7 @@ connected to other testbeds for experiments involving wide area layer2 networks.
5.8 Metrics API 5.8 Metrics API
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
5.8.1 Get the timeseries corresponding to a job 5.8.1 Get some timeseries (and plot them)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Credits to ``lturpin``.
.. code:: python
import logging
import os
from grid5000 import Grid5000
logging.basicConfig(level=logging.DEBUG)
def get_job_consumption(job_id, gk, site):
metrics = gk.sites[site].metrics
job = gk.sites[site].jobs[job_id]
# nodes as list : "cluster-number.site.grid5000.fr"
nodes_dom = job.assigned_nodes
# nodes as list : "cluster-number"
nodes = map(lambda node_dom: node_dom.split('.')[0], nodes_dom)
# nodes as string : "cluster-number,cluster-number,..."
nodes_str = ','.join(nodes)
start = job.started_at
end = job.stopped_at
kwargs = {
"only": nodes_str,
"resolution": 1,
"from": start,
"to": end
}
timeseries = metrics["power"].timeseries.list(**kwargs)
return timeseries
conf_file = os.path.join(os.environ.get("HOME"), ".python-grid5000.yaml")
gk = Grid5000.from_yaml(conf_file)
timeseries = get_job_consumption("1092446", gk, "lyon")
print(timeseries)
5.8.2 Get some timeseries (and plot them)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For this example you’ll need ``matplotlib``, ``seaborn`` and ``pandas``. For this example you’ll need ``matplotlib``, ``seaborn`` and ``pandas``.
...@@ -675,45 +632,40 @@ For this example you’ll need ``matplotlib``, ``seaborn`` and ``pandas``. ...@@ -675,45 +632,40 @@ For this example you’ll need ``matplotlib``, ``seaborn`` and ``pandas``.
import seaborn as sns import seaborn as sns
import time import time
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.INFO)
conf_file = os.path.join(os.environ.get("HOME"), ".python-grid5000.yaml") conf_file = os.path.join(os.environ.get("HOME"), ".python-grid5000.yaml")
gk = Grid5000.from_yaml(conf_file) gk = Grid5000.from_yaml(conf_file)
metrics = gk.sites["lyon"].metrics metrics = gk.sites["lyon"].clusters["nova"].metrics
print("--- available metrics") print("--- available metrics")
print(metrics.list()) print(metrics)
print("---- power metric")
print(metrics["power"])
print("----- a timeserie") print("----- a timeserie")
now = time.time() now = time.time()
# NOTE that you can pass a job_id here
kwargs = { kwargs = {
"only": "nova-1,nova-2,nova-3", "nodes": "nova-1,nova-2,nova-3",
"resolution": 1, "metrics": "wattmetre_power_watt",
"from": int(now - 600), "start_time": int(now - 600),
"to": int(now)
} }
timeseries = metrics["power"].timeseries.list(**kwargs) metrics = gk.sites["lyon"].metrics.list(**kwargs)
# let's visualize this # let's visualize this
df = pd.DataFrame() df = pd.DataFrame()
for timeserie in timeseries: for metric in metrics:
print(timeserie) timestamp = metric.timestamp
timestamp = timeserie.timestamps value = metric.value
value = timeserie.values device_id = metric.device_id
measurement = timeserie.uid
df = pd.concat([df, pd.DataFrame({ df = pd.concat([df, pd.DataFrame({
"timestamp": timestamp, "timestamp": [timestamp],
"value": value, "value": [value],
"measurement": [measurement]*len(timestamp) "device_id": [device_id]
})]) })])
sns.relplot(data=df, sns.relplot(data=df,
x="timestamp", x="timestamp",
y="value", y="value",
hue="measurement", hue="device_id",
kind="line") kind="line")
plt.show() plt.show()
......
...@@ -19,6 +19,7 @@ from .__version__ import __version__ ...@@ -19,6 +19,7 @@ from .__version__ import __version__
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
DEFAULT_BASE_URL = "https://api.grid5000.fr/stable" DEFAULT_BASE_URL = "https://api.grid5000.fr/stable"
DEFAULT_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"
USER_AGENT = "python-grid5000 %s" % __version__ USER_AGENT = "python-grid5000 %s" % __version__
...@@ -61,7 +62,7 @@ class Grid5000(object): ...@@ -61,7 +62,7 @@ class Grid5000(object):
uri=DEFAULT_BASE_URL, uri=DEFAULT_BASE_URL,
username=None, username=None,
password=None, password=None,
verify_ssl=True, verify_ssl=None,
timeout=None, timeout=None,
session=None, session=None,
sslcert=None, sslcert=None,
...@@ -74,6 +75,18 @@ class Grid5000(object): ...@@ -74,6 +75,18 @@ class Grid5000(object):
self.username = username self.username = username
self.password = password self.password = password
self.verify_ssl = verify_ssl self.verify_ssl = verify_ssl
if self.verify_ssl is None:
# By default, requests ignores trusted CA from the system
# (it uses certifi instead).
# On Grid'5000 frontend and nodes, it is necessary to use the
# system CA bundle, because it includes the root Grid'5000 CA
# allowing to validate the internal API certificate.
ca_bundle = Path(DEFAULT_CA_BUNDLE)
if ca_bundle.exists():
self.verify_ssl = ca_bundle
else:
# As a last resort, use certifi
self.verify_ssl = True
self.client_ssl = False self.client_ssl = False
self.client_cert = None self.client_cert = None
......
...@@ -20,24 +20,30 @@ MOTD = r""" ...@@ -20,24 +20,30 @@ MOTD = r"""
\____/_/ /_/\__,_/ /_____/\____/\____/\____/ \____/_/ /_/\__,_/ /_____/\____/\____/\____/
* Configuration loaded from %s """
* A new client (variable gk) has been created for the user %s
MOTD_END = """\
* Start exploring the API through the gk variable * Start exploring the API through the gk variable
# Example: Get all available sites # Example: Get all available sites
$) gk.sites.list() $) gk.sites.list()
""" """
def main(): def main():
path = pathlib.Path(CONF_PATH) path = pathlib.Path(CONF_PATH)
if not path.exists(): motd = MOTD
print("Configuration file %s is missing" % CONF_PATH) if path.exists():
return gk = Grid5000.from_yaml(CONF_PATH)
gk = Grid5000.from_yaml(CONF_PATH) motd += "* Configuration loaded from %s\n" % CONF_PATH
motd = MOTD % (CONF_PATH, gk.username) else:
IPython.embed(header=motd) gk = Grid5000()
motd += "* Warning: configuration file %s is missing, authentication might not work\n" % CONF_PATH
if gk.username:
motd += "* A new client (variable gk) has been created for the user %s\n" % gk.username
else:
motd += "* A new client (variable gk) has been created\n"
motd += MOTD_END
IPython.embed(header=motd, colors="neutral")
def auth(user: str): def auth(user: str):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment