diff --git a/awx/api/serializers.py b/awx/api/serializers.py index e8df13ab3e..e38efff349 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -57,6 +57,7 @@ from awx.main.models import ( Host, Instance, InstanceGroup, + InstanceLink, Inventory, InventorySource, InventoryUpdate, @@ -4767,6 +4768,28 @@ class ScheduleSerializer(LaunchConfigurationBaseSerializer, SchedulePreviewSeria return super(ScheduleSerializer, self).validate(attrs) +class InstanceLinkSerializer(BaseSerializer): + class Meta: + model = InstanceLink + fields = ('source', 'target') + + source = serializers.SlugRelatedField(slug_field="hostname", read_only=True) + target = serializers.SlugRelatedField(slug_field="hostname", read_only=True) + + +class InstanceNodeSerializer(BaseSerializer): + class Meta: + model = Instance + fields = ('id', 'hostname', 'node_type', 'node_state') + + node_state = serializers.SerializerMethodField() + + def get_node_state(self, obj): + if not obj.enabled: + return "disabled" + return "unhealthy" if obj.errors else "healthy" + + class InstanceSerializer(BaseSerializer): consumed_capacity = serializers.SerializerMethodField() diff --git a/awx/api/templates/api/mesh_visualizer.md b/awx/api/templates/api/mesh_visualizer.md new file mode 100644 index 0000000000..89902af5da --- /dev/null +++ b/awx/api/templates/api/mesh_visualizer.md @@ -0,0 +1 @@ +Make a GET request to this resource to obtain a list all Receptor Nodes and their links. diff --git a/awx/api/urls/urls.py b/awx/api/urls/urls.py index 9985de6ee1..017fa307aa 100644 --- a/awx/api/urls/urls.py +++ b/awx/api/urls/urls.py @@ -28,6 +28,7 @@ from awx.api.views import ( OAuth2TokenList, ApplicationOAuth2TokenList, OAuth2ApplicationDetail, + MeshVisualizer, ) from awx.api.views.metrics import MetricsView @@ -95,6 +96,7 @@ v2_urls = [ url(r'^me/$', UserMeList.as_view(), name='user_me_list'), url(r'^dashboard/$', DashboardView.as_view(), name='dashboard_view'), url(r'^dashboard/graphs/jobs/$', DashboardJobsGraphView.as_view(), name='dashboard_jobs_graph_view'), + url(r'^mesh_visualizer/', MeshVisualizer.as_view(), name='mesh_visualizer_view'), url(r'^settings/', include('awx.conf.urls')), url(r'^instances/', include(instance_urls)), url(r'^instance_groups/', include(instance_group_urls)), diff --git a/awx/api/views/__init__.py b/awx/api/views/__init__.py index 3dc6881333..9907a91092 100644 --- a/awx/api/views/__init__.py +++ b/awx/api/views/__init__.py @@ -159,6 +159,7 @@ from awx.api.views.inventory import ( # noqa InventoryJobTemplateList, InventoryCopy, ) +from awx.api.views.mesh_visualizer import MeshVisualizer # noqa from awx.api.views.root import ( # noqa ApiRootView, ApiOAuthAuthorizationRootView, diff --git a/awx/api/views/mesh_visualizer.py b/awx/api/views/mesh_visualizer.py new file mode 100644 index 0000000000..517f8762fb --- /dev/null +++ b/awx/api/views/mesh_visualizer.py @@ -0,0 +1,23 @@ +# Copyright (c) 2018 Red Hat, Inc. +# All Rights Reserved. + +from awx.main.models import InstanceLink, Instance +from django.utils.translation import ugettext_lazy as _ + +from awx.api.generics import APIView, Response + +from awx.api.serializers import InstanceLinkSerializer, InstanceNodeSerializer + + +class MeshVisualizer(APIView): + + name = _("Mesh Visualizer") + + def get(self, request, format=None): + + data = { + 'nodes': InstanceNodeSerializer(Instance.objects.all(), many=True).data, + 'links': InstanceLinkSerializer(InstanceLink.objects.all(), many=True).data, + } + + return Response(data) diff --git a/awx/api/views/root.py b/awx/api/views/root.py index 2f7f49a122..763576cb2f 100644 --- a/awx/api/views/root.py +++ b/awx/api/views/root.py @@ -123,6 +123,7 @@ class ApiVersionRootView(APIView): data['workflow_approvals'] = reverse('api:workflow_approval_list', request=request) data['workflow_job_template_nodes'] = reverse('api:workflow_job_template_node_list', request=request) data['workflow_job_nodes'] = reverse('api:workflow_job_node_list', request=request) + data['mesh_visualizer_view'] = reverse('api:mesh_visualizer_view', request=request) return Response(data)