add instance install bundle endpoint

add scaffolding for instance install_bundle endpoint

- add instance_install_bundle view (does not do anything yet)
- add `instance_install_bundle` related field to serializer
- add `/install_bundle` to instance URL
- `/install_bundle` only available for execution and hop node
- `/install_bundle` endpoint response contain a downloadable tgz with moc data

TODO: add actual data to the install bundle response

Signed-off-by: Hao Liu <haoli@redhat.com>
This commit is contained in:
TheRealHaoLiu
2022-07-18 11:10:59 -04:00
committed by Jeff Bradberry
parent 9b034ad574
commit 7956fc3c31
4 changed files with 58 additions and 1 deletions

View File

@@ -174,6 +174,7 @@ from awx.api.views.webhooks import WebhookKeyView, GithubWebhookReceiver, Gitlab
from awx.api.pagination import UnifiedJobEventPagination
from awx.main.utils import set_environ
from awx.api.views.instance_install_bundle import InstanceInstallBundle # noqa
logger = logging.getLogger('awx.api.views')

View File

@@ -0,0 +1,54 @@
# Copyright (c) 2018 Red Hat, Inc.
# All Rights Reserved.
import os
import tarfile
import tempfile
from awx.api import serializers
from awx.api.generics import GenericAPIView, Response
from awx.api.permissions import IsSystemAdminOrAuditor
from awx.main import models
from django.utils.translation import gettext_lazy as _
from rest_framework import status
from django.http import HttpResponse
# generate install bundle for the instance
class InstanceInstallBundle(GenericAPIView):
name = _('Install Bundle')
model = models.Instance
serializer_class = serializers.InstanceSerializer
permission_classes = (IsSystemAdminOrAuditor,)
def get(self, request, *args, **kwargs):
instance_obj = self.get_object()
# if the instance is not a hop or execution node than return 400
if instance_obj.node_type not in ('execution', 'hop'):
return Response(
data=dict(msg=_('Install bundle can only be generated for execution or hop nodes.')),
status=status.HTTP_400_BAD_REQUEST,
)
# TODO: add actual data into the bundle
# create a named temporary file directory to store the content of the install bundle
with tempfile.TemporaryDirectory() as tmpdirname:
# create a empty file named "moc_content.txt" in the temporary directory
with open(os.path.join(tmpdirname, 'mock_content.txt'), 'w') as f:
f.write('mock content')
# create empty directory in temporary directory
os.mkdir(os.path.join(tmpdirname, 'mock_dir'))
# tar.gz and create a temporary file from the temporary directory
# the directory will be renamed and prefixed with the hostname of the instance
with tempfile.NamedTemporaryFile(suffix='.tar.gz') as tmpfile:
with tarfile.open(tmpfile.name, 'w:gz') as tar:
tar.add(tmpdirname, arcname=f"{instance_obj.hostname}_install_bundle")
# read the temporary file and send it to the client
with open(tmpfile.name, 'rb') as f:
response = HttpResponse(f.read(), status=status.HTTP_200_OK)
response['Content-Disposition'] = f"attachment; filename={instance_obj.hostname}_install_bundle.tar.gz"
return response