Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/gcp_scanner/client/client_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from gcp_scanner.client.cloud_functions_client import CloudFunctionsClient
from gcp_scanner.client.cloud_resource_manager_client import CloudResourceManagerClient
from gcp_scanner.client.compute_client import ComputeClient
from gcp_scanner.client.container_client import ContainerClient
from gcp_scanner.client.datastore_client import DatastoreClient
from gcp_scanner.client.dns_client import DNSClient
from gcp_scanner.client.domains_client import DomainsClient
Expand Down Expand Up @@ -49,6 +50,7 @@ class ClientFactory:
"cloudkms": CloudKMSClient,
"cloudresourcemanager": CloudResourceManagerClient,
"compute": ComputeClient,
"container": ContainerClient,
"datastore": DatastoreClient,
"domains": DomainsClient,
"dns": DNSClient,
Expand Down
38 changes: 38 additions & 0 deletions src/gcp_scanner/client/container_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from google.cloud import container_v1
from httplib2 import Credentials

from .interface_client import IClient


class ContainerClient(IClient):
"""ContainerClient class."""

def get_service(
self,
credentials: Credentials,
) -> container_v1.services.cluster_manager.client.ClusterManagerClient:
"""Get service for GKE container resources.

Args:
credentials: An google.oauth2.credentials.Credentials object.

Returns:
A ClusterManagerClient.
"""
return container_v1.services.cluster_manager.ClusterManagerClient(
credentials=credentials,
)
4 changes: 1 addition & 3 deletions src/gcp_scanner/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,9 +370,7 @@ def iam_client_for_credentials(
def gke_client_for_credentials(
credentials: Credentials,
) -> container_v1.services.cluster_manager.client.ClusterManagerClient:
return container_v1.services.cluster_manager.ClusterManagerClient(
credentials=credentials
)
return ClientFactory.get_client("container").get_service(credentials)


def get_sa_details_from_key_files(key_path):
Expand Down
22 changes: 22 additions & 0 deletions src/gcp_scanner/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from .client.cloud_functions_client import CloudFunctionsClient
from .client.cloud_resource_manager_client import CloudResourceManagerClient
from .client.compute_client import ComputeClient
from .client.container_client import ContainerClient
from .client.datastore_client import DatastoreClient
from .client.dns_client import DNSClient
from .client.domains_client import DomainsClient
Expand Down Expand Up @@ -887,6 +888,27 @@ def test_get_client_compute(self):
client = ClientFactory.get_client("compute")
self.assertIsInstance(client, ComputeClient)

def test_get_client_container(self):
"""Test get_client method with 'container' name."""
client = ClientFactory.get_client("container")
self.assertIsInstance(client, ContainerClient)

@patch(
"gcp_scanner.client.container_client.container_v1.services."
"cluster_manager.ClusterManagerClient"
)
def test_container_client_get_service(self, mock_cluster_manager_client):
"""Test ContainerClient creates the GKE cluster manager client."""
credentials_obj = Mock()
client = ContainerClient()

service = client.get_service(credentials_obj)

self.assertEqual(service, mock_cluster_manager_client.return_value)
mock_cluster_manager_client.assert_called_once_with(
credentials=credentials_obj,
)

def test_get_client_appengine(self):
"""Test get_client method with 'appengine' name."""
client = ClientFactory.get_client("appengine")
Expand Down