# -*- 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)