diff --git a/CHANGELOG.md b/CHANGELOG.md index 62707982e3fd96fae87a7024bfa89b6305782133..1f7751880a5466fe2f5ca965383791e9b932d102 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 1.2.2 + +- Get cleaner (client) endpoinf for the storage API # 1.2.1 - StorageHomeUser now uses id as __attr_id (fix an issue in `__repr__`) diff --git a/README.org b/README.org index f1dfa85f0665aa98202106123eac4c028c8f7222..538621236bcd658a667d64af9917a9a7b63f36e6 100644 --- a/README.org +++ b/README.org @@ -366,42 +366,46 @@ In [2]: # gk is your entry point conf_file = os.path.join(os.environ.get("HOME"), ".python-grid5000.yaml") gk = Grid5000.from_yaml(conf_file) - print(gk.sites["rennes"].storage["msimonin"].access.list()) + print(gk.sites["rennes"].storage["home"].access["msimonin"].rules.list()) #+END_SRC *** Set storage accesses (e.g for vms) #+BEGIN_SRC python :exports code :tangle examples/storage_set.py - from netaddr import IPNetwork - import logging - import os - import time + from netaddr import IPNetwork + import logging + import os + import time - from grid5000 import Grid5000 + from grid5000 import Grid5000 - logging.basicConfig(level=logging.DEBUG) + logging.basicConfig(level=logging.DEBUG) - conf_file = os.path.join(os.environ.get("HOME"), ".python-grid5000.yaml") - gk = Grid5000.from_yaml(conf_file) - site = gk.sites["rennes"] + conf_file = os.path.join(os.environ.get("HOME"), ".python-grid5000.yaml") + gk = Grid5000.from_yaml(conf_file) + site = gk.sites["rennes"] - job = site.jobs.create({"name": "pyg5k", - "command": "sleep 3600", - "resources": "slash_22=1+nodes=1"}) + job = site.jobs.create({"name": "pyg5k", + "command": "sleep 3600", + "resources": "slash_22=1+nodes=1"}) - while job.state != "running": - job.refresh() - print("Waiting the job [%s] to be running" % job.uid) - time.sleep(5) + while job.state != "running": + job.refresh() + print("Waiting the job [%s] to be running" % job.uid) + time.sleep(5) + + subnet = job.resources_by_type['subnets'][0] + ip_network = [str(ip) for ip in IPNetwork(subnet)] - subnet = job.resources_by_type['subnets'][0] - ip_network = [str(ip) for ip in IPNetwork(subnet)] + # create acces for all ips in the subnet + access = site.storage["home"].access["msimonin"].rules.create({"ipv4": ip_network, + "termination": { + "job": job.uid, + "site": site.uid}}) - # create acces for all ips in the subnet - access = site.storage["msimonin"].access.create({"ipv4": ip_network, - "termination": {"job": job.uid, - "site": site.uid}}) + # listing the accesses + print(gk.sites["rennes"].storage["home"].access["msimonin"].rules.list()) #+END_SRC ** Vlan API diff --git a/examples/storage_accesses.py b/examples/storage_accesses.py index 32f80452e5100cee615c03412ef6ccae90022098..d35c55d251c631eab63c4e962f4bb1204580a608 100644 --- a/examples/storage_accesses.py +++ b/examples/storage_accesses.py @@ -9,4 +9,4 @@ logging.basicConfig(level=logging.DEBUG) conf_file = os.path.join(os.environ.get("HOME"), ".python-grid5000.yaml") gk = Grid5000.from_yaml(conf_file) -print(gk.sites["rennes"].storage["msimonin"].access.list()) +print(gk.sites["rennes"].storage["home"].access["msimonin"].rules.list()) diff --git a/examples/storage_set.py b/examples/storage_set.py index 93e2eb6eec1156eea5f304ed061db103b9facf0a..0397a0c1c796137b2a9f84726828fe6561b2bdc6 100644 --- a/examples/storage_set.py +++ b/examples/storage_set.py @@ -25,6 +25,10 @@ subnet = job.resources_by_type['subnets'][0] ip_network = [str(ip) for ip in IPNetwork(subnet)] # create acces for all ips in the subnet -access = site.storage["msimonin"].access.create({"ipv4": ip_network, - "termination": {"job": job.uid, +access = site.storage["home"].access["msimonin"].rules.create({"ipv4": ip_network, + "termination": { + "job": job.uid, "site": site.uid}}) + +# listing the accesses +print(gk.sites["rennes"].storage["home"].access["msimonin"].rules.list()) diff --git a/grid5000/objects.py b/grid5000/objects.py index 9435c37ad2362e8f09085e462ca5041651c552d6..4d626f5ff96ac015efdc45e8635f887aee055864 100644 --- a/grid5000/objects.py +++ b/grid5000/objects.py @@ -62,12 +62,21 @@ class Deployment(RESTObject, RefreshMixin): ) -class StorageHomeUser(RESTObject): - _id_attr = "id" +class StorageGroup(RESTObject): + _id_attr = "uid" + _managers = (("access", "StorageGroupAccessManager"),) + +class StorageGroupAccess(RESTObject): + pass -class StorageHome(RESTObject): - _managers = (("access", "StorageHomeUserManager"),) + +class StorageGroupAccessList(RESTObject): + _managers = (("rules", "StorageGroupAccessListRulesManager"),) + + +class StorageGroupAccessListRule(RESTObject): + _id_attr = "id" class Node(RESTObject): @@ -117,7 +126,7 @@ class Site(RESTObject): ("network_equipments", "SiteNetworkEquipmentManager"), ("servers", "ServerManager"), ("status", "SiteStatusManager"), - ("storage", "StorageHomeManager"), + ("storage", "StorageManager"), ("vlans", "VlanManager"), ("vlansnodes", "VlanNodeManager"), ("vlansusers", "VlanUserManager"), @@ -162,26 +171,46 @@ class NodeManager(RetrieveMixin, BracketMixin, RESTManager): _from_parent_attrs = {"site": "site", "cluster": "uid"} -class StorageHomeManager(RESTManager): - _path = "/sites/%(site)s/storage/home" - _obj_cls = StorageHome +class StorageManager(RESTManager, BracketMixin): + _path = "/sites/%(site)s/storage" + _obj_cls = StorageGroup _from_parent_attrs = {"site": "uid"} # NOTE(msimonin): grr ... need to fix the return values because it's not # consistent with the rest of API - # So we fake a return value + # home access: /sites/site/storage/home/username/access + # group storage access: sites/site/server/storage/access (but here storage isn't fixed) + + # we transform that in something more restful + # - sites["rennes"].storage["home"] + # - sites["rennes"].storage["storage1"] + # To get a specific Manager based on the storage location (home or group + # storage on a dedicated server) + + # On which we can perform regular operations on the access endpoint + # - sites["rennes"].storage["home"].access.[list|create] + # - sites["rennes"].storage["storage1"].access.[list|create] + @exc.on_http_error(exc.Grid5000GetError) def __getitem__(self, key): return self._obj_cls(self, {"uid": key}) -class StorageHomeUserManager(RESTManager): - _path = "/sites/%(site)s/storage/home/%(user)s/access" - _obj_cls = StorageHomeUser - _from_parent_attrs = {"site": "site", "user": "uid"} +class StorageGroupAccessManager(RESTManager, BracketMixin): + _path = "/sites/%(site)s/storage/%(server)s/" + _obj_cls = StorageGroupAccessList + _from_parent_attrs = {"site": "site", "server": "uid"} + + @exc.on_http_error(exc.Grid5000GetError) + def __getitem__(self, key): + return self._obj_cls(self, {"uid": key}) + + +class StorageGroupAccessListRulesManager(RESTManager, BracketMixin): + _path = "/sites/%(site)s/storage/%(server)s/%(storage)s/access" + _obj_cls = StorageGroupAccessListRule + _from_parent_attrs = {"site": "site", "server": "server", "storage": "uid"} - # NOTE(msimonin): grr ... need to fix the return values because it's not - # consistent with the rest of API @exc.on_http_error(exc.Grid5000GetError) def list(self, **kwargs): """Retrieve a list of objects.