def Adjust(self, resource): """Mutates the given config's volumes to match the desired changes. Args: resource: k8s_object to adjust Returns: The adjusted resource Raises: ConfigurationError if there's an attempt to replace the volume a mount points to whose existing volume has a source of a different type than the new volume (e.g. mount that points to a volume with a secret source can't be replaced with a volume that has a config map source). """ volume_mounts = resource.template.volume_mounts.secrets volumes = resource.template.volumes.secrets # TODO(b/182412304): This is not going to work on secrets in the same dir # (but it could be made to work if they're versions of one secret.) if platforms.IsManaged(): removes = [p.rsplit('/', 1)[0] for p in self._removes] else: removes = self._removes _PruneMapping(volume_mounts, removes, self._clear_others) for file_path, reachable_secret in self._updates.items(): volume_name = _UniqueVolumeName(reachable_secret.secret_name, resource.template.volumes) # volume_mounts is a special mapping that filters for the current kind # of mount and KeyErrors on existing keys with other types. try: mount_point = file_path if platforms.IsManaged(): # TODO(b/182412304): SubPath handling is not ready. mount_point = file_path.rsplit('/', 1)[0] volume_mounts[mount_point] = volume_name except KeyError: raise exceptions.ConfigurationError( 'Cannot update mount [{}] because its mounted volume ' 'is of a different source type.'.format(file_path)) volumes[volume_name] = reachable_secret.AsSecretVolumeSource( resource) _PruneVolumes(volume_mounts, volumes) secrets_mapping.PruneAnnotation(resource) return resource
def _OmittedSecretKeyDefault(self, name): """The key/version value to use for a secret flag that has no version. Args: name: The env var or mount point, for use in an error message. Returns: str value to use as the secret version. Raises: ConfigurationError: If the key is required on this platform. """ if self.force_managed or platforms.IsManaged(): # Service returns an error for this, but we can make a better one. raise exceptions.ConfigurationError( 'No secret version specified for {name}. ' 'Use {name}:latest to reference the latest version.'.format( name=name)) else: # for GKE+K8S if self._connector is SpecialConnector.PATH_OR_ENV: raise TypeError( "Can't determine default key for secret named %r." % name) if not self._connector.startswith('/'): raise exceptions.ConfigurationError( 'Missing required item key for the secret at [{}].'.format( name)) else: # for a mount point return SpecialVersion.MOUNT_ALL
def __init__(self, flag_value, connector_name, force_managed=False): """Parse flag value to make a ReachableSecret. Args: flag_value: str. A secret identifier like 'sec1:latest'. See tests for other supported formats (which vary by platform). connector_name: Union[str, PATH_OR_ENV]. An env var ('ENV1') or a mount point ('/a/b') for use in error messages. Also used in validation since you can only use MOUNT_ALL mode with a mount path. force_managed: bool. If True, always use the behavior of managed Cloud Run even if the platform is set to gke. Used by Cloud Run local development. """ self._connector = connector_name self.force_managed = force_managed if force_managed or platforms.IsManaged(): match = re.search(self._REMOTE_SECRET_FLAG_VALUE, flag_value) if match: self.remote_project_number = match.group('project') self.secret_name = match.group('secret') self.secret_version = match.group('version_short') if self.secret_version is None: self.secret_version = match.group('version_long') if self.secret_version is None: self.secret_version = 'latest' return self._InitWithLocalSecret(flag_value, connector_name)
def AsSecretVolumeSource(self, resource): """Build message for adding to resource.template.volumes.secrets. Args: resource: k8s_object that may get modified with new aliases. Returns: messages.SecretVolumeSource """ if platforms.IsManaged(): return self._AsSecretVolumeSource_ManagedMode(resource) else: return self._AsSecretVolumeSource_NonManagedMode(resource)
def _OmittedSecretKeyDefault(self, name): if platforms.IsManaged(): return 'latest' raise exceptions.ConfigurationError( 'Missing required item key for environment variable [{}].'.format( name))