Skip to content

Commit 769c2a9

Browse files
AAP-36964 - API endpoint to scaffold devfile using ansible-creator add subcommand (#553)
* adding initital changes * chore: auto fixes from pre-commit.com hooks * fixed path var * fixes * docstring changes * removed the collection param * chore: auto fixes from pre-commit.com hooks * comment fix * added pytest * chore: auto fixes from pre-commit.com hooks * added test case * chore: auto fixes from pre-commit.com hooks * fixes 2 --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent b25bcbb commit 769c2a9

File tree

4 files changed

+107
-0
lines changed

4 files changed

+107
-0
lines changed

src/ansible_dev_tools/resources/server/creator_v2.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from ansible_creator._version import version as creator_version
1111
from ansible_creator.config import Config
1212
from ansible_creator.output import Output
13+
from ansible_creator.subcommands.add import Add
1314
from ansible_creator.subcommands.init import Init
1415
from ansible_creator.utils import TermFeatures
1516
from django.core.files.storage import FileSystemStorage
@@ -104,6 +105,30 @@ def collection(
104105
response=response,
105106
)
106107

108+
def devfile(
109+
self,
110+
request: HttpRequest,
111+
) -> FileResponse | HttpResponse:
112+
"""Add a devfile.
113+
114+
Args:
115+
request: HttpRequest object.
116+
117+
Returns:
118+
File or error response.
119+
"""
120+
result = validate_request(request)
121+
if isinstance(result, HttpResponse):
122+
return result
123+
with tempfile.TemporaryDirectory() as tmp_dir:
124+
tar_file = CreatorBackend(Path(tmp_dir)).devfile()
125+
response = self._response_from_tar(tar_file)
126+
127+
return validate_response(
128+
request=request,
129+
response=response,
130+
)
131+
107132

108133
class CreatorOutput(Output):
109134
"""The creator output."""
@@ -190,3 +215,26 @@ def playbook(
190215
tar_file = self.tmp_dir / f"{namespace}-{collection_name}.tar"
191216
create_tar_file(init_path, tar_file)
192217
return tar_file
218+
219+
def devfile(self) -> Path:
220+
"""Scaffold a devfile.
221+
222+
Returns:
223+
The tar file path.
224+
"""
225+
# Path where the devfile is going to be added
226+
add_path = self.tmp_dir / "devfile"
227+
add_path.mkdir(parents=True, exist_ok=True)
228+
229+
config = Config(
230+
resource_type="devfile",
231+
creator_version=creator_version,
232+
path=str(add_path),
233+
output=CreatorOutput(log_file=str(self.tmp_dir / "creator.log")),
234+
subcommand="add",
235+
overwrite=True,
236+
)
237+
Add(config).run()
238+
tar_file = self.tmp_dir / "devfile.tar"
239+
create_tar_file(add_path, tar_file)
240+
return tar_file

src/ansible_dev_tools/resources/server/data/openapi.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,22 @@ paths:
102102
application/json:
103103
schema:
104104
$ref: "#/components/schemas/Error"
105+
/v2/creator/devfile:
106+
post:
107+
summary: Create a new devfile project
108+
responses:
109+
"201":
110+
description: Created
111+
content:
112+
application/tar:
113+
schema:
114+
AnyValue: {}
115+
"400":
116+
description: Bad Request
117+
content:
118+
application/json:
119+
schema:
120+
$ref: "#/components/schemas/Error"
105121

106122
components:
107123
schemas:

src/ansible_dev_tools/subcommands/server.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
path(route="v1/creator/collection", view=CreatorFrontendV1().collection),
2828
path(route="v2/creator/playbook", view=CreatorFrontendV2().playbook),
2929
path(route="v2/creator/collection", view=CreatorFrontendV2().collection),
30+
path(route="v2/creator/devfile", view=CreatorFrontendV2().devfile),
3031
)
3132

3233

tests/integration/test_server_creator_v2.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@ def test_error_v2(server_url: str, resource: str) -> None:
2727
assert response.text == "Missing required request body"
2828

2929

30+
def test_error_devfile_v2(server_url: str) -> None:
31+
"""Test the error response when a request body is sent unexpectedly.
32+
33+
Args:
34+
server_url: The server URL.
35+
36+
Raises:
37+
AssertionError: If the test assertions fail (e.g., response status code or tar content).
38+
"""
39+
# To simulate an error, we are sending the request with the get method as the api works with empty request body as well.
40+
response = requests.get(f"{server_url}/v2/creator/devfile", timeout=10)
41+
assert response.status_code == requests.codes.get("bad_request"), (
42+
f"Expected 400 but got {response.status_code}"
43+
)
44+
assert response.text == "Operation get not found for " + f"{server_url}/v2/creator/devfile"
45+
46+
3047
def test_playbook_v2(server_url: str, tmp_path: Path) -> None:
3148
"""Test the playbook creation.
3249
@@ -79,3 +96,28 @@ def test_collection_v2(server_url: str, tmp_path: Path) -> None:
7996
tar_file.write(response.content)
8097
with tarfile.open(dest_file) as file:
8198
assert "./roles/run/tasks/main.yml" in file.getnames()
99+
100+
101+
def test_devfile_v2(server_url: str, tmp_path: Path) -> None:
102+
"""Test the devfile creation.
103+
104+
Args:
105+
server_url: The server URL.
106+
tmp_path: Pytest tmp_path fixture.
107+
108+
Raises:
109+
AssertionError: If the test assertions fail (e.g., response status code or tar content).
110+
"""
111+
response = requests.post(
112+
f"{server_url}/v2/creator/devfile",
113+
json={},
114+
timeout=10,
115+
)
116+
assert response.status_code == requests.codes.get("created")
117+
assert response.headers["Content-Disposition"] == 'attachment; filename="devfile.tar"'
118+
assert response.headers["Content-Type"] == "application/tar"
119+
dest_file = tmp_path / "devfile.tar"
120+
with dest_file.open(mode="wb") as tar_file:
121+
tar_file.write(response.content)
122+
with tarfile.open(dest_file) as file:
123+
assert "./devfile.yaml" in file.getnames()

0 commit comments

Comments
 (0)