mirror of
https://github.com/ansible/awx.git
synced 2026-01-22 15:08:03 -03:30
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:
parent
9b034ad574
commit
7956fc3c31
@ -4917,6 +4917,7 @@ class InstanceSerializer(BaseSerializer):
|
||||
res = super(InstanceSerializer, self).get_related(obj)
|
||||
res['jobs'] = self.reverse('api:instance_unified_jobs_list', kwargs={'pk': obj.pk})
|
||||
res['instance_groups'] = self.reverse('api:instance_instance_groups_list', kwargs={'pk': obj.pk})
|
||||
res['install_bundle'] = self.reverse('api:instance_install_bundle', kwargs={'pk': obj.pk})
|
||||
if self.context['request'].user.is_superuser or self.context['request'].user.is_system_auditor:
|
||||
if obj.node_type != 'hop':
|
||||
res['health_check'] = self.reverse('api:instance_health_check', kwargs={'pk': obj.pk})
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
from django.urls import re_path
|
||||
|
||||
from awx.api.views import InstanceList, InstanceDetail, InstanceUnifiedJobsList, InstanceInstanceGroupsList, InstanceHealthCheck
|
||||
from awx.api.views import InstanceList, InstanceDetail, InstanceUnifiedJobsList, InstanceInstanceGroupsList, InstanceHealthCheck, InstanceInstallBundle
|
||||
|
||||
|
||||
urls = [
|
||||
@ -12,6 +12,7 @@ urls = [
|
||||
re_path(r'^(?P<pk>[0-9]+)/jobs/$', InstanceUnifiedJobsList.as_view(), name='instance_unified_jobs_list'),
|
||||
re_path(r'^(?P<pk>[0-9]+)/instance_groups/$', InstanceInstanceGroupsList.as_view(), name='instance_instance_groups_list'),
|
||||
re_path(r'^(?P<pk>[0-9]+)/health_check/$', InstanceHealthCheck.as_view(), name='instance_health_check'),
|
||||
re_path(r'^(?P<pk>[0-9]+)/install_bundle/$', InstanceInstallBundle.as_view(), name='instance_install_bundle'),
|
||||
]
|
||||
|
||||
__all__ = ['urls']
|
||||
|
||||
@ -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')
|
||||
|
||||
|
||||
54
awx/api/views/instance_install_bundle.py
Normal file
54
awx/api/views/instance_install_bundle.py
Normal 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
|
||||
Loading…
x
Reference in New Issue
Block a user