Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[COST-5114] Add type ahead support for the new EC2 fields #5159

Merged
merged 8 commits into from
Jul 17, 2024
68 changes: 68 additions & 0 deletions docs/specs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -3256,6 +3256,74 @@
}
}
},
"/resource-types/aws-ec2-compute-instances/": {
"get": {
"tags": [
"Resource Type"
],
"summary": "List AWS EC2 Instances For RBAC",
"operationId": "listResourcesAwsEC2Instances",
"parameters": [{
"$ref": "#/components/parameters/QueryOffset"
},
{
"$ref": "#/components/parameters/QueryLimit"
},
{
"$ref": "#/components/parameters/QueryValue"
},
{
"$ref": "#/components/parameters/QueryOrder"
}
],
"responses": {
"200": {
"description": "| - 200 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResourceTypePagination"
}
}
}
}
}
}
},
"/resource-types/aws-ec2-compute-os/": {
"get": {
"tags": [
"Resource Type"
],
"summary": "List AWS EC2 Operating Systems For RBAC",
"operationId": "listResourcesAwsEC2OperatingSystems",
"parameters": [{
"$ref": "#/components/parameters/QueryOffset"
},
{
"$ref": "#/components/parameters/QueryLimit"
},
{
"$ref": "#/components/parameters/QueryValue"
},
{
"$ref": "#/components/parameters/QueryOrder"
}
],
"responses": {
"200": {
"description": "| - 200 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResourceTypePagination"
}
}
}
}
}
}
},
"/resource-types/gcp-accounts/": {
"get": {
"tags": [
Expand Down
Empty file.
60 changes: 60 additions & 0 deletions koku/api/resource_types/aws_ec2_compute_instances/view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#
# Copyright 2024 Red Hat Inc.
# SPDX-License-Identifier: Apache-2.0
#
"""View for AWS EC2 instances."""
from django.conf import settings
from django.db.models import F
from django.db.models.functions import Coalesce
from django.utils.decorators import method_decorator
from django.views.decorators.vary import vary_on_headers
from rest_framework import filters
from rest_framework import generics
from rest_framework import status
from rest_framework.response import Response

from api.common import CACHE_RH_IDENTITY_HEADER
from api.common.pagination import ResourceTypeViewPaginator
from api.common.permissions.aws_access import AwsAccessPermission
from api.resource_types.serializers import ResourceTypeSerializer
from reporting.provider.aws.models import AWSCostEntryLineItemSummaryByEC2Compute


class AWSEC2ComputeInstanceView(generics.ListAPIView):
"""API GET list view for AWS EC2 compute instances."""

queryset = (
AWSCostEntryLineItemSummaryByEC2Compute.objects.annotate(
value=F("resource_id"), ec2_instance_name=Coalesce(F("instance_name"), "resource_id")
)
.values("value", "ec2_instance_name")
.distinct()
)

serializer_class = ResourceTypeSerializer
permission_classes = [AwsAccessPermission]
filter_backends = [filters.OrderingFilter, filters.SearchFilter]
ordering = ["value", "ec2_instance_name"]
search_fields = ["value", "ec2_instance_name"]
pagination_class = ResourceTypeViewPaginator

@method_decorator(vary_on_headers(CACHE_RH_IDENTITY_HEADER))
def list(self, request):
# Reads the aws ec2 compute instances info and displays values related to what the user has access to.
supported_query_params = ["search", "limit"]
user_access = None
error_message = {}
# Test for only supported query_params
if self.request.query_params:
for key in self.request.query_params:
if key not in supported_query_params:
error_message[key] = [{"Unsupported parameter"}]
return Response(error_message, status=status.HTTP_400_BAD_REQUEST)
if settings.ENHANCED_ORG_ADMIN and request.user.admin:
return super().list(request)
elif request.user.access:
user_access = request.user.access.get("aws.account", {}).get("read", [])
if user_access and user_access[0] == "*":
return super().list(request)
self.queryset = self.queryset.filter(usage_account_id__in=user_access)
return super().list(request)
Empty file.
59 changes: 59 additions & 0 deletions koku/api/resource_types/aws_ec2_compute_os/view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#
# Copyright 2024 Red Hat Inc.
# SPDX-License-Identifier: Apache-2.0
#
"""View for AWS EC2 operating systems."""
from django.conf import settings
from django.db.models import F
from django.utils.decorators import method_decorator
from django.views.decorators.vary import vary_on_headers
from rest_framework import filters
from rest_framework import generics
from rest_framework import status
from rest_framework.response import Response

from api.common import CACHE_RH_IDENTITY_HEADER
from api.common.pagination import ResourceTypeViewPaginator
from api.common.permissions.aws_access import AwsAccessPermission
from api.resource_types.serializers import ResourceTypeSerializer
from reporting.provider.aws.models import AWSCostEntryLineItemSummaryByEC2Compute


class AWSEC2ComputeOperatingSystemView(generics.ListAPIView):
"""API GET list view for AWS EC2 compute operating systems."""

queryset = (
AWSCostEntryLineItemSummaryByEC2Compute.objects.annotate(value=F("operating_system"))
.values("value")
.distinct()
.filter(operating_system__isnull=False)
)

serializer_class = ResourceTypeSerializer
permission_classes = [AwsAccessPermission]
filter_backends = [filters.OrderingFilter, filters.SearchFilter]
ordering = ["value"]
search_fields = ["value"]
pagination_class = ResourceTypeViewPaginator

@method_decorator(vary_on_headers(CACHE_RH_IDENTITY_HEADER))
def list(self, request):
# Reads the aws ec2 compute instance info and displays values related to what the user has access to.
supported_query_params = ["search", "limit"]
user_access = []
error_message = {}
# Test for only supported query_params
if self.request.query_params:
for key in self.request.query_params:
if key not in supported_query_params:
error_message[key] = [{"Unsupported parameter"}]
return Response(error_message, status=status.HTTP_400_BAD_REQUEST)
djnakabaale marked this conversation as resolved.
Show resolved Hide resolved
if settings.ENHANCED_ORG_ADMIN and request.user.admin:
return super().list(request)
elif request.user.access:
user_access = request.user.access.get("aws.account", {}).get("read", [])
if user_access and user_access[0] == "*":
return super().list(request)
self.queryset = self.queryset.filter(usage_account_id__in=user_access)

return super().list(request)
1 change: 1 addition & 0 deletions koku/api/resource_types/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ class ResourceTypeSerializer(serializers.Serializer):
extra_kwargs = {"test": {"error_messages": {"required": "Give yourself a username"}}}
cluster_alias = serializers.CharField(source="ocp_cluster_alias", required=False)
account_alias = serializers.CharField(source="alias", required=False)
instance_name = serializers.CharField(source="ec2_instance_name", required=False)
value = serializers.CharField()
10 changes: 9 additions & 1 deletion koku/api/resource_types/test/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,15 @@ class ResourceTypesViewTest(IamTestCase):
"""Tests the resource types views."""

ENDPOINTS_RTYPE = ["resource-types"]
ENDPOINTS_AWS = ["aws-accounts", "aws-regions", "aws-services", "aws-organizational-units", "aws-categories"]
ENDPOINTS_AWS = [
"aws-accounts",
"aws-regions",
"aws-services",
"aws-organizational-units",
"aws-categories",
"aws-ec2-compute-instances",
"aws-ec2-compute-os",
]
ENDPOINTS_GCP = ["gcp-accounts", "gcp-projects", "gcp-regions", "gcp-services"]
ENDPOINTS_AZURE = ["azure-subscription-guids", "azure-services", "azure-regions"]
ENDPOINTS_OPENSHIFT = ["openshift-clusters", "openshift-nodes", "openshift-projects"]
Expand Down
12 changes: 12 additions & 0 deletions koku/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
from api.views import AWSCategoryView
from api.views import AWSCostForecastView
from api.views import AWSCostView
from api.views import AWSEC2ComputeInstanceView
from api.views import AWSEC2ComputeOperatingSystemView
from api.views import AWSInstanceTypeView
from api.views import AWSOrganizationalUnitView
from api.views import AWSOrgView
Expand Down Expand Up @@ -396,6 +398,16 @@
path("resource-types/", ResourceTypeView.as_view(), name="resource-types"),
path("user-access/", UserAccessView.as_view(), name="user-access"),
path("resource-types/aws-accounts/", AWSAccountView.as_view(), name="aws-accounts"),
path(
"resource-types/aws-ec2-compute-instances/",
AWSEC2ComputeInstanceView.as_view(),
name="aws-ec2-compute-instances",
),
path(
"resource-types/aws-ec2-compute-os/",
AWSEC2ComputeOperatingSystemView.as_view(),
name="aws-ec2-compute-os",
),
path(
"resource-types/aws-categories/",
cache_page(timeout=settings.CACHE_MIDDLEWARE_SECONDS, key_prefix=AWS_CACHE_PREFIX)(AWSCategoryView.as_view()),
Expand Down
2 changes: 2 additions & 0 deletions koku/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
from api.report.ocp.view import OCPVolumeView
from api.resource_types.aws_accounts.view import AWSAccountView
from api.resource_types.aws_category.view import AWSCategoryView
from api.resource_types.aws_ec2_compute_instances.view import AWSEC2ComputeInstanceView
from api.resource_types.aws_ec2_compute_os.view import AWSEC2ComputeOperatingSystemView
from api.resource_types.aws_org_unit.view import AWSOrganizationalUnitView
from api.resource_types.aws_regions.view import AWSAccountRegionView
from api.resource_types.aws_services.view import AWSServiceView
Expand Down
Loading