File: //snap/google-cloud-cli/current/lib/googlecloudsdk/api_lib/container/gkemulticloud/attached.py
# -*- coding: utf-8 -*- #
# Copyright 2025 Google LLC. All Rights Reserved.
#
# 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
#
# http://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.
"""Base class for gkemulticloud API clients for Attached resources."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.container.gkemulticloud import client
from googlecloudsdk.api_lib.container.gkemulticloud import update_mask
from googlecloudsdk.command_lib.container.attached import flags as attached_flags
from googlecloudsdk.command_lib.container.gkemulticloud import flags
class _AttachedClientBase(client.ClientBase):
"""Base class for Attached gkemulticloud API clients."""
def _Cluster(self, cluster_ref, args):
cluster_type = self._messages.GoogleCloudGkemulticloudV1AttachedCluster
kwargs = {
'annotations': self._Annotations(args, cluster_type),
'binaryAuthorization': self._BinaryAuthorization(args),
'platformVersion': attached_flags.GetPlatformVersion(args),
'fleet': self._Fleet(args),
'name': cluster_ref.attachedClustersId,
'description': flags.GetDescription(args),
'oidcConfig': self._OidcConfig(args),
'distribution': attached_flags.GetDistribution(args),
'authorization': self._Authorization(args),
'loggingConfig': flags.GetLogging(args, True),
'monitoringConfig': flags.GetMonitoringConfig(args),
'proxyConfig': self._ProxyConfig(args),
'securityPostureConfig': self._SecurityPosture(args),
'tags': self._TagBindings(args, cluster_type),
'systemComponentsConfig': self._SystemComponentsConfig(args),
}
return (
self._messages.GoogleCloudGkemulticloudV1AttachedCluster(**kwargs)
if any(kwargs.values())
else None
)
def _OidcConfig(self, args):
kwargs = {
'issuerUrl': attached_flags.GetIssuerUrl(args),
}
oidc = attached_flags.GetOidcJwks(args)
if oidc:
kwargs['jwks'] = oidc.encode(encoding='utf-8')
return (
self._messages.GoogleCloudGkemulticloudV1AttachedOidcConfig(**kwargs)
if any(kwargs.values())
else None
)
def _ProxyConfig(self, args):
secret_name = attached_flags.GetProxySecretName(args)
secret_namespace = attached_flags.GetProxySecretNamespace(args)
if secret_name or secret_namespace:
kwargs = {
'kubernetesSecret':
self._messages.GoogleCloudGkemulticloudV1KubernetesSecret(
name=secret_name,
namespace=secret_namespace,
)
}
return (
self._messages.GoogleCloudGkemulticloudV1AttachedProxyConfig(
**kwargs
)
)
return None
def _Authorization(self, args):
admin_users = attached_flags.GetAdminUsers(args)
admin_groups = flags.GetAdminGroups(args)
if not admin_users and not admin_groups:
return None
kwargs = {}
if admin_users:
kwargs['adminUsers'] = [
self._messages.GoogleCloudGkemulticloudV1AttachedClusterUser(
username=u
)
for u in admin_users
]
if admin_groups:
kwargs['adminGroups'] = [
self._messages.GoogleCloudGkemulticloudV1AttachedClusterGroup(group=g)
for g in admin_groups
]
if not any(kwargs.values()):
return None
return (
self._messages.GoogleCloudGkemulticloudV1AttachedClustersAuthorization(
**kwargs
)
)
def _SystemComponentsConfig(self, args):
labels = attached_flags.GetSystemComponentLabels(args)
tolerations = attached_flags.GetSystemComponentTolerations(args)
if not labels and not tolerations:
return None
kwargs = {}
if tolerations:
kwargs['tolerations'] = [
self._messages.GoogleCloudGkemulticloudV1Toleration(
key=t[0],
value=t[1],
keyOperator=self._ConvertTolerationOperator(t[2]),
effect=self._ConvertTolerationEffect(t[3]),
)
for t in tolerations
]
if labels:
kwargs['labels'] = [
self._messages.GoogleCloudGkemulticloudV1Label(
key=key,
value=labels[key],
)
for key in labels
]
return self._messages.GoogleCloudGkemulticloudV1SystemComponentsConfig(
**kwargs
)
def _ConvertTolerationOperator(self, operator):
if operator.lower() == 'exists':
return self._messages.GoogleCloudGkemulticloudV1Toleration.KeyOperatorValueValuesEnum(
'KEY_OPERATOR_EXISTS'
)
if operator.lower() == 'equal':
return self._messages.GoogleCloudGkemulticloudV1Toleration.KeyOperatorValueValuesEnum(
'KEY_OPERATOR_EQUAL'
)
return self._messages.GoogleCloudGkemulticloudV1Toleration.KeyOperatorValueValuesEnum(
'KEY_OPERATOR_UNSPECIFIED'
)
def _ConvertTolerationEffect(self, effect):
standardized_effect = effect.lower()
if standardized_effect == 'noschedule':
return self._messages.GoogleCloudGkemulticloudV1Toleration.EffectValueValuesEnum(
'EFFECT_NO_SCHEDULE'
)
if standardized_effect == 'noexecute':
return self._messages.GoogleCloudGkemulticloudV1Toleration.EffectValueValuesEnum(
'EFFECT_NO_EXECUTE'
)
if standardized_effect == 'prefernoschedule':
return self._messages.GoogleCloudGkemulticloudV1Toleration.EffectValueValuesEnum(
'EFFECT_PREFER_NO_SCHEDULE'
)
return self._messages.GoogleCloudGkemulticloudV1Toleration.EffectValueValuesEnum(
'EFFECT_UNSPECIFIED'
)
class ClustersClient(_AttachedClientBase):
"""Client for Attached Clusters in the gkemulticloud API."""
def __init__(self, **kwargs):
super(ClustersClient, self).__init__(**kwargs)
self._service = self._client.projects_locations_attachedClusters
self._list_result_field = 'attachedClusters'
def Create(self, cluster_ref, args):
"""Creates an Attached cluster."""
req = self._messages.GkemulticloudProjectsLocationsAttachedClustersCreateRequest(
parent=cluster_ref.Parent().RelativeName(),
googleCloudGkemulticloudV1AttachedCluster=self._Cluster(
cluster_ref, args
),
attachedClusterId=cluster_ref.attachedClustersId,
validateOnly=flags.GetValidateOnly(args),
)
return self._service.Create(req)
def Update(self, cluster_ref, args):
"""Updates an Attached cluster."""
req = self._messages.GkemulticloudProjectsLocationsAttachedClustersPatchRequest(
googleCloudGkemulticloudV1AttachedCluster=self._Cluster(
cluster_ref, args
),
name=cluster_ref.RelativeName(),
updateMask=update_mask.GetUpdateMask(
args, update_mask.ATTACHED_CLUSTER_ARGS_TO_UPDATE_MASKS
),
validateOnly=flags.GetValidateOnly(args),
)
return self._service.Patch(req)
def Import(self, location_ref, fleet_membership_ref, args):
"""Imports an Attached cluster fleet membership."""
req = self._messages.GkemulticloudProjectsLocationsAttachedClustersImportRequest(
parent=location_ref.RelativeName(),
googleCloudGkemulticloudV1ImportAttachedClusterRequest=self._messages.GoogleCloudGkemulticloudV1ImportAttachedClusterRequest(
fleetMembership=fleet_membership_ref.RelativeName(),
platformVersion=attached_flags.GetPlatformVersion(args),
distribution=attached_flags.GetDistribution(args),
proxyConfig=self._ProxyConfig(args),
validateOnly=flags.GetValidateOnly(args),
),
)
return self._service.Import(req)