ttafsir / evengsdk

Open source Python library and command line utilities for EVE-NG API
https://ttafsir.github.io/evengsdk/
MIT License
63 stars 14 forks source link

Windows - Unable to delete a lab in a subdirectory #93

Open seanblundy opened 2 years ago

seanblundy commented 2 years ago

Summary

I am unable to remove a nested lab via this library.

Issue Type

Bug Report

Python Version

3.8.10

OS / Environment

Windows 10

Steps to Reproduce

On a Windows system, attempt to delete a lab in a subdirectory.

Expected Results

Lab is deleted successfully.

Actual Results

Exception has occurred: ValueError
WindowsPath('//Ansible/test_lab.unl/') has an empty name
  File "C:\Projects\autolab\app.py", line 22, in <module>
    client.api.delete_lab(lab)

Comments

This is due to the Path import being ambiguous, and as a result will use the system Pathlib, which in my case is WindowsPath.

Discovered Solution

By replacing the import with PurePosixPath and removing the .resolve(), I am able to utilize the SDK. Perhaps introduce a check for the OS the user is on and substitute these function calls?

https://github.com/ttafsir/evengsdk/blob/4d8cf338fa860a8c22930594239f64a499425043/src/evengsdk/api.py#L5 https://github.com/ttafsir/evengsdk/blob/4d8cf338fa860a8c22930594239f64a499425043/src/evengsdk/api.py#L152

mplattner commented 2 years ago

There's already a PR that fixes this. It's applied in the develop branch, but I guess will be in the main branch as well soon. See #62

ttafsir commented 2 years ago

I pulled the changes in, but I have no real way to test without Windows. Please let me know. Thank you!!

seanblundy commented 2 years ago

So, an update with 0.2.2:

It works.

However, it only works when the path is correctly specified. (e.g. /Ansible/test_lab.unl). The downside here being that the eve-ng API returns poor POSIX paths such as: //Ansible/test_lab.unl, which are natively handled on Unix gracefully (Tested via Ubuntu 20.04), but not Windows.

Steps to Reproduce:

As a result of this, attempting to use a direct output of the API results in:

>>> from pathlib import PurePosixPath
>>> resp = client.api.get_folder("/")
>>> resp
{
  "code": 200,
  "status": "success",
  "message": "Successfully listed path (60007).",
  "data": {
    "folders": [
      { "name": "..", "path": "/" },
      { "name": "Ansible", "path": "///Ansible" }
    ],
    "labs": []
  }
}

>>> folder = 'Ansible'
>>> resp = client.api.get_folder(folder)
>>> resp
{
  "code": 200,
  "status": "success",
  "message": "Successfully listed path (60007).",
  "data": {
    "folders": [{ "name": "..", "path": "/" }],
    "labs": [
      {
        "file": "test_lab.unl",
        "path": "//Ansible/test_lab.unl",
        "umtime": 1643087601,
        "mtime": "25 Jan 2022  06:13"
      }
    ]
  }
}

>>> lab = resp['data']['labs'][0]['path']
>>> lab
'//Ansible/test_lab.unl'
>>> client.api.delete_lab(lab)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\\Projects\autolab\venv\lib\site-packages\evengsdk\api.py", line 767, in delete_lab
    url = "/labs" + self.normalize_path(path)
  File "C:\\Projects\autolab\venv\lib\site-packages\evengsdk\api.py", line 155, in normalize_path
    path = path.with_suffix(".unl")
  File "C:\Python38\lib\pathlib.py", line 872, in with_suffix
    raise ValueError("%r has an empty name" % (self,))
ValueError: WindowsPath('//Ansible/test_lab.unl/') has an empty name
ttafsir commented 2 years ago

So, an update with 0.2.2:

It works.

However, it only works when the path is correctly specified. (e.g. /Ansible/test_lab.unl). The downside here being that the eve-ng API returns poor POSIX paths such as: //Ansible/test_lab.unl, which are natively handled on Unix gracefully (Tested via Ubuntu 20.04), but not Windows.

Steps to Reproduce:

As a result of this, attempting to use a direct output of the API results in:

>>> from pathlib import PurePosixPath
>>> resp = client.api.get_folder("/")
>>> resp
{
  "code": 200,
  "status": "success",
  "message": "Successfully listed path (60007).",
  "data": {
    "folders": [
      { "name": "..", "path": "/" },
      { "name": "Ansible", "path": "///Ansible" }
    ],
    "labs": []
  }
}

>>> folder = 'Ansible'
>>> resp = client.api.get_folder(folder)
>>> resp
{
  "code": 200,
  "status": "success",
  "message": "Successfully listed path (60007).",
  "data": {
    "folders": [{ "name": "..", "path": "/" }],
    "labs": [
      {
        "file": "test_lab.unl",
        "path": "//Ansible/test_lab.unl",
        "umtime": 1643087601,
        "mtime": "25 Jan 2022  06:13"
      }
    ]
  }
}

>>> lab = resp['data']['labs'][0]['path']
>>> lab
'//Ansible/test_lab.unl'
>>> client.api.delete_lab(lab)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\\Projects\autolab\venv\lib\site-packages\evengsdk\api.py", line 767, in delete_lab
    url = "/labs" + self.normalize_path(path)
  File "C:\\Projects\autolab\venv\lib\site-packages\evengsdk\api.py", line 155, in normalize_path
    path = path.with_suffix(".unl")
  File "C:\Python38\lib\pathlib.py", line 872, in with_suffix
    raise ValueError("%r has an empty name" % (self,))
ValueError: WindowsPath('//Ansible/test_lab.unl/') has an empty name

I see. I should have a Windows set up here pretty soon to see if I can replicate the issue.