Atualizar buckets para um usuário do SFTP

Este documento mostra como atualizar os buckets do Cloud Storage para um usuário do Cloud FTP, incluindo quais buckets um usuário pode acessar e quais permissões ele tem.

Em um nível alto, estas são as etapas para atualizar os buckets de um usuário:

  1. Atualize os papéis do IAM da conta de serviço do usuário.
  2. Mapeie os diretórios do usuário para os buckets atualizados.

Antes de começar

Funções exigidas

Para receber a permissão necessária para atualizar usuários do SFTP, peça ao administrador para conceder a você o papel do IAM de administrador do FTP (roles/ftp.admin) no projeto. Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Esse papel predefinido contém a ftp.users.update permissão, que é necessária para atualizar usuários do SFTP.

Também é possível conseguir essa permissão com papéis personalizados ou outros papéis predefinidos.

Atualizar papéis do IAM para a conta de serviço de um usuário

Se você mudar os buckets que um usuário pode acessar ou a permissão que ele tem para um mapeamento de diretório atual, será necessário atualizar a conta de serviço do usuário com os papéis do IAM relevantes. Faça o seguinte:

  1. Confira o endereço de e-mail da conta de serviço do usuário. Para conferir as etapas, consulte Conferir detalhes sobre um usuário.

  2. Se você adicionar novos buckets ao mapeamento de diretório ou aumentar o acesso a buckets atuais, faça o seguinte:

    1. Conceda a si mesmo o papel de Leitor de buckets do Storage (roles/storage.bucketViewer) no bucket, se você ainda não tiver o papel:

      gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
          --member="user:ADMINISTRATOR_EMAIL" \
          --role="roles/storage.bucketViewer"

      Substitua:

      • ADMINISTRATOR_EMAIL: o endereço de e-mail do principal que está criando o usuário do SFTP. Se você estiver criando o usuário (em vez de um aplicativo), esse valor será o endereço de e-mail usado para acessar Google Cloud.

      • BUCKET_NAME: o nome do bucket

    2. Conceda a si mesmo o papel de Leitor de objetos do Storage (roles/storage.objectViewer) no bucket, se você ainda não tiver o papel:

      gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
          --member="user:ADMINISTRATOR_EMAIL" \
          --role="roles/storage.objectViewer"
    3. Conceda à conta de serviço do usuário os papéis do IAM necessários para acessar os buckets:

      gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
        --member="serviceAccount:SERVICE_ACCOUNT" \
        --role="ROLE_TO_GRANT"

      Substitua:

      • SERVICE_ACCOUNT: o endereço de e-mail da conta de serviço do usuário.
      • ROLE_TO_GRANT: o papel do IAM a ser concedido. Especifique um dos seguintes papéis:

        • Para acesso somente leitura, use o papel roles/storage.objectViewer.
        • Para acesso de leitura e gravação, use o papel roles/storage.objectAdmin.
    4. Repita as etapas anteriores para cada bucket que o usuário precisa acessar.

  3. Se você remover buckets do mapeamento de diretório ou diminuir o acesso a buckets atuais, revogue o acesso da conta de serviço do usuário:

    gcloud storage buckets remove-iam-policy-binding gs://BUCKET_NAME \
      --member="serviceAccount:SERVICE_ACCOUNT" \
      --role="ROLE_TO_REVOKE"

    Substitua ROLE_TO_REVOKE pelo papel do IAM que você quer revogar.

    Repita essa etapa para cada bucket e papel do IAM que o usuário não deve mais ter acesso.

Atualizar os buckets de um usuário

gcloud

Para atualizar os buckets de um usuário do SFTP, execute o gcloud alpha storage ftp users update comando.

Antes de usar os dados do comando abaixo, faça estas substituições:

  • USERNAME: o nome de usuário do SFTP.
  • LOCATION_ID: o local do servidor, como us-west1.
  • SERVER_ID: o ID do servidor.
  • BUCKET_NAME: o nome de um bucket ao qual o usuário do SFTP tem acesso, como example-bucket. Omita o gs://.
  • (Opcional) BUCKET_PREFIX: o caminho de uma pasta dentro do bucket a ser definido como o diretório raiz para esse mapeamento de diretório. Se você omitir a propriedade bucket_prefix, então o Cloud FTP usará a raiz do bucket.
  • DIRECTORY: o caminho do diretório de destino lógico apresentado ao usuário do SFTP. Por exemplo, /home/uploads.

    Se você mapear vários buckets ou pastas, forneça um caminho de diretório exclusivo para cada mapeamento.

    Não há suporte para diretórios lógicos aninhados. Se você fornecer vários mapeamentos para um diretório, forneça os diretórios em uma estrutura simples em vez de uma estrutura aninhada. Por exemplo, use /dir1 e /dir2 em vez de /dir1 e /dir1/dir2.

  • SFTP_PERMISSION: o nível de acesso ao diretório. Para acesso somente leitura, defina este valor como READ_ONLY. Para acesso de leitura e gravação, defina esse valor como READ_WRITE.

Para conceder a um usuário acesso a vários buckets, forneça a --storage-directory-mapping flag várias vezes, com um mapeamento de diretório para cada bucket.

Execute o comando a seguir:

Linux, macOS ou Cloud Shell

gcloud alpha storage ftp users update USERNAME --location=LOCATION_ID \
    --server=SERVER_ID \
    --storage-directory-mapping=bucket=BUCKET_NAME,bucket_prefix=BUCKET_PREFIX,directory=DIRECTORY,permission=SFTP_PERMISSION

Windows (PowerShell)

gcloud alpha storage ftp users update USERNAME --location=LOCATION_ID `
    --server=SERVER_ID `
    --storage-directory-mapping=bucket=BUCKET_NAME,bucket_prefix=BUCKET_PREFIX,directory=DIRECTORY,permission=SFTP_PERMISSION

Windows (cmd.exe)

gcloud alpha storage ftp users update USERNAME --location=LOCATION_ID ^
    --server=SERVER_ID ^
    --storage-directory-mapping=bucket=BUCKET_NAME,bucket_prefix=BUCKET_PREFIX,directory=DIRECTORY,permission=SFTP_PERMISSION
Leva alguns segundos para o usuário ser atualizado.

Se um usuário tiver uma conexão SFTP ativa, talvez seja necessário desconectar e reconectar para que as configurações de bucket atualizadas entrem em vigor.

REST

Para atualizar os buckets de um usuário do SFTP, use o servers.users.patch método. No parâmetro de consulta updateMask, forneça o campo storageDirectoryMappings.

Antes de usar os dados da solicitação abaixo, faça estas substituições:

  • PROJECT_ID: o Google Cloud ID do projeto do servidor.
  • LOCATION_ID: o local do servidor, como us-west1.
  • SERVER_ID: o ID do servidor.
  • USERNAME: o nome de usuário do SFTP.
  • BUCKET_NAME: o nome de um bucket ao qual o usuário do SFTP tem acesso, como example-bucket. Omita o gs://.
  • (Opcional) BUCKET_PREFIX: o caminho de uma pasta dentro do bucket a ser definido como o diretório raiz para esse mapeamento de diretório. Se você omitir esse valor, o Cloud FTP usará a raiz do bucket raiz.
  • DIRECTORY: o caminho do diretório de destino lógico apresentado ao usuário do SFTP. Por exemplo, /home/uploads. Se você omitir esse valor, o Cloud FTP definirá o diretório de destino como /.

    Se você mapear vários buckets ou pastas, forneça um caminho de diretório exclusivo para cada mapeamento.

    Não há suporte para diretórios lógicos aninhados. Se você fornecer vários mapeamentos para um diretório, forneça os diretórios em uma estrutura simples em vez de uma estrutura aninhada. Por exemplo, use /dir1 e /dir2 em vez de /dir1 e /dir1/dir2.

  • SFTP_PERMISSION: o nível de acesso ao diretório. Para acesso somente leitura, defina este valor como READ_ONLY. Para acesso de leitura e gravação, defina esse valor como READ_WRITE.

Para conceder a um usuário acesso a vários buckets, forneça vários mapeamentos de bucket na storageDirectoryMappings lista.

Método HTTP e URL:

PATCH https://ftp.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION_ID/servers/SERVER_ID/users/USERNAME?updateMask=storageDirectoryMappings

Corpo JSON da solicitação:

{
  "storageDirectoryMappings": [
    {
      "bucket": "BUCKET_NAME",
      "bucketPrefix": "BUCKET_PREFIX",
      "directory": "DIRECTORY",
      "permission": "SFTP_PERMISSION"
    }
  ]
}

Para enviar a solicitação, expanda uma destas opções:

A resposta identifica uma operação de longa duração. Leva alguns segundos para o usuário ser atualizado.

Se um usuário tiver uma conexão SFTP ativa, talvez seja necessário desconectar e reconectar para que as configurações de bucket atualizadas entrem em vigor.

Bibliotecas de cliente

C#

Para saber como instalar e usar a biblioteca de cliente do Cloud FTP, consulte Bibliotecas de cliente do Cloud FTP. Para mais informações, consulte a documentação de referência da API Cloud FTPC#.

Para se autenticar no Cloud FTP, configure o Application Default Credentials. Se quiser mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

using Google.Cloud.Ftp.V1;
using Google.LongRunning;
using Google.Protobuf.WellKnownTypes;
using System.Threading.Tasks;

public sealed partial class GeneratedCloudFtpClientSnippets
{
    /// <summary>Snippet for UpdateUserAsync</summary>
    /// <remarks>
    /// This snippet has been automatically generated and should be regarded as a code template only.
    /// It will require modifications to work:
    /// - It may require correct/in-range values for request initialization.
    /// - It may require specifying regional endpoints when creating the service client as shown in
    ///   https://cloud.google.com/dotnet/docs/reference/help/client-configuration#endpoint.
    /// </remarks>
    public async Task UpdateUserAsync()
    {
        // Create client
        CloudFtpClient cloudFtpClient = await CloudFtpClient.CreateAsync();
        // Initialize request argument(s)
        User user = new User();
        FieldMask updateMask = new FieldMask();
        // Make the request
        Operation<User, OperationMetadata> response = await cloudFtpClient.UpdateUserAsync(user, updateMask);

        // Poll until the returned long-running operation is complete
        Operation<User, OperationMetadata> completedResponse = await response.PollUntilCompletedAsync();
        // Retrieve the operation result
        User result = completedResponse.Result;

        // Or get the name of the operation
        string operationName = response.Name;
        // This name can be stored, then the long-running operation retrieved later by name
        Operation<User, OperationMetadata> retrievedResponse = await cloudFtpClient.PollOnceUpdateUserAsync(operationName);
        // Check if the retrieved long-running operation has completed
        if (retrievedResponse.IsCompleted)
        {
            // If it has completed, then access the result
            User retrievedResult = retrievedResponse.Result;
        }
    }
}

Go

Para saber como instalar e usar a biblioteca de cliente do Cloud FTP, consulte Bibliotecas de cliente do Cloud FTP. Para mais informações, consulte a Cloud FTP Go API documentação de referência.

Para se autenticar no Cloud FTP, configure o Application Default Credentials. Se quiser mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.


//go:build examples

package main

import (
	"context"

	ftp "cloud.google.com/go/ftp/apiv1"
	ftppb "cloud.google.com/go/ftp/apiv1/ftppb"
)

func main() {
	ctx := context.Background()
	// This snippet has been automatically generated and should be regarded as a code template only.
	// It will require modifications to work:
	// - It may require correct/in-range values for request initialization.
	// - It may require specifying regional endpoints when creating the service client as shown in:
	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
	c, err := ftp.NewCloudFtpRESTClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	defer c.Close()

	req := &ftppb.UpdateUserRequest{
		// TODO: Fill request struct fields.
		// See https://pkg.go.dev/cloud.google.com/go/ftp/apiv1/ftppb#UpdateUserRequest.
	}
	op, err := c.UpdateUser(ctx, req)
	if err != nil {
		// TODO: Handle error.
	}

	resp, err := op.Wait(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}

Java

Para saber como instalar e usar a biblioteca de cliente do Cloud FTP, consulte Bibliotecas de cliente do Cloud FTP. Para mais informações, consulte a APIJava Cloud FTP documentação de referência.

Para se autenticar no Cloud FTP, configure o Application Default Credentials. Se quiser mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

import com.google.api.core.ApiFuture;
import com.google.cloud.ftp.v1.CloudFtpClient;
import com.google.cloud.ftp.v1.UpdateUserRequest;
import com.google.cloud.ftp.v1.User;
import com.google.longrunning.Operation;
import com.google.protobuf.FieldMask;

public class AsyncUpdateUser {

  public static void main(String[] args) throws Exception {
    asyncUpdateUser();
  }

  public static void asyncUpdateUser() throws Exception {
    // This snippet has been automatically generated and should be regarded as a code template only.
    // It will require modifications to work:
    // - It may require correct/in-range values for request initialization.
    // - It may require specifying regional endpoints when creating the service client as shown in
    // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
    try (CloudFtpClient cloudFtpClient = CloudFtpClient.create()) {
      UpdateUserRequest request =
          UpdateUserRequest.newBuilder()
              .setUpdateMask(FieldMask.newBuilder().build())
              .setUser(User.newBuilder().build())
              .build();
      ApiFuture<Operation> future = cloudFtpClient.updateUserCallable().futureCall(request);
      // Do something.
      Operation response = future.get();
    }
  }
}

Node.js

Para saber como instalar e usar a biblioteca de cliente do Cloud FTP, consulte Bibliotecas de cliente do Cloud FTP. Para mais informações, consulte a documentação de referência da API Node.js Cloud FTP.

Para se autenticar no Cloud FTP, configure o Application Default Credentials. Se quiser mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

/**
 * This snippet has been automatically generated and should be regarded as a code template only.
 * It will require modifications to work.
 * It may require correct/in-range values for request initialization.
 * TODO(developer): Uncomment these variables before running the sample.
 */
/**
 *  Optional. Field mask is used to specify the fields to be overwritten in the
 *  User resource by the update.
 *  The fields specified in the update_mask are relative to the resource, not
 *  the full request. A field will be overwritten if it is in the mask. If the
 *  user does not provide a mask then all fields present in the request will be
 *  overwritten.
 */
// const updateMask = {}
/**
 *  Required. The resource being updated
 */
// const user = {}

// Imports the Ftp library
const {CloudFtpClient} = require('@google-cloud/ftp').v1;

// Instantiates a client
const ftpClient = new CloudFtpClient();

async function callUpdateUser() {
  // Construct request
  const request = {
    user,
  };

  // Run request
  const [operation] = await ftpClient.updateUser(request);
  const [response] = await operation.promise();
  console.log(response);
}

callUpdateUser();

PHP

Para saber como instalar e usar a biblioteca de cliente do Cloud FTP, consulte Bibliotecas de cliente do Cloud FTP. Para mais informações, consulte a Cloud FTP PHP API documentação de referência.

Para se autenticar no Cloud FTP, configure o Application Default Credentials. Se quiser mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

use Google\ApiCore\ApiException;
use Google\ApiCore\OperationResponse;
use Google\Cloud\Ftp\V1\Client\CloudFtpClient;
use Google\Cloud\Ftp\V1\StorageDirectoryMapping;
use Google\Cloud\Ftp\V1\StorageDirectoryMapping\Permission;
use Google\Cloud\Ftp\V1\UpdateUserRequest;
use Google\Cloud\Ftp\V1\User;
use Google\Cloud\Ftp\V1\UserCredential;
use Google\Cloud\Ftp\V1\UserCredential\Type;
use Google\Rpc\Status;

/**
 * Updates the parameters of a single User.
 *
 * @param string $userCustomerServiceAccount             Service account in customer project attached to this SFTP User.
 * @param string $userUserCredentialsCredentialName      Name of the user credential.
 * @param int    $userUserCredentialsCredentialType      Type of credential.
 * @param string $userStorageDirectoryMappingsBucket     Name of the bucket.
 * @param string $userStorageDirectoryMappingsDirectory  Directory where the user lands in the SFTP server.
 * @param int    $userStorageDirectoryMappingsPermission Permission to the bucket.
 */
function update_user_sample(
    string $userCustomerServiceAccount,
    string $userUserCredentialsCredentialName,
    int $userUserCredentialsCredentialType,
    string $userStorageDirectoryMappingsBucket,
    string $userStorageDirectoryMappingsDirectory,
    int $userStorageDirectoryMappingsPermission
): void {
    // Create a client.
    $cloudFtpClient = new CloudFtpClient();

    // Prepare the request message.
    $userCredential = (new UserCredential())
        ->setCredentialName($userUserCredentialsCredentialName)
        ->setCredentialType($userUserCredentialsCredentialType);
    $userUserCredentials = [$userCredential];
    $storageDirectoryMapping = (new StorageDirectoryMapping())
        ->setBucket($userStorageDirectoryMappingsBucket)
        ->setDirectory($userStorageDirectoryMappingsDirectory)
        ->setPermission($userStorageDirectoryMappingsPermission);
    $userStorageDirectoryMappings = [$storageDirectoryMapping];
    $user = (new User())
        ->setCustomerServiceAccount($userCustomerServiceAccount)
        ->setUserCredentials($userUserCredentials)
        ->setStorageDirectoryMappings($userStorageDirectoryMappings);
    $request = (new UpdateUserRequest())
        ->setUser($user);

    // Call the API and handle any network failures.
    try {
        /** @var OperationResponse $response */
        $response = $cloudFtpClient->updateUser($request);
        $response->pollUntilComplete();

        if ($response->operationSucceeded()) {
            /** @var User $result */
            $result = $response->getResult();
            printf('Operation successful with response data: %s' . PHP_EOL, $result->serializeToJsonString());
        } else {
            /** @var Status $error */
            $error = $response->getError();
            printf('Operation failed with error data: %s' . PHP_EOL, $error->serializeToJsonString());
        }
    } catch (ApiException $ex) {
        printf('Call failed with message: %s' . PHP_EOL, $ex->getMessage());
    }
}

/**
 * Helper to execute the sample.
 *
 * This sample has been automatically generated and should be regarded as a code
 * template only. It will require modifications to work:
 *  - It may require correct/in-range values for request initialization.
 *  - It may require specifying regional endpoints when creating the service client,
 *    please see the apiEndpoint client configuration option for more details.
 */
function callSample(): void
{
    $userCustomerServiceAccount = '[CUSTOMER_SERVICE_ACCOUNT]';
    $userUserCredentialsCredentialName = '[CREDENTIAL_NAME]';
    $userUserCredentialsCredentialType = Type::TYPE_UNSPECIFIED;
    $userStorageDirectoryMappingsBucket = '[BUCKET]';
    $userStorageDirectoryMappingsDirectory = '[DIRECTORY]';
    $userStorageDirectoryMappingsPermission = Permission::PERMISSION_UNSPECIFIED;

    update_user_sample(
        $userCustomerServiceAccount,
        $userUserCredentialsCredentialName,
        $userUserCredentialsCredentialType,
        $userStorageDirectoryMappingsBucket,
        $userStorageDirectoryMappingsDirectory,
        $userStorageDirectoryMappingsPermission
    );
}

Python

Para saber como instalar e usar a biblioteca de cliente do Cloud FTP, consulte Bibliotecas de cliente do Cloud FTP. Para mais informações, consulte a APIPython Cloud FTP documentação de referência.

Para se autenticar no Cloud FTP, configure o Application Default Credentials. Se quiser mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

# This snippet has been automatically generated and should be regarded as a
# code template only.
# It will require modifications to work:
# - It may require correct/in-range values for request initialization.
# - It may require specifying regional endpoints when creating the service
#   client as shown in:
#   https://googleapis.dev/python/google-api-core/latest/client_options.html
from google.cloud import ftp_v1


def sample_update_user():
    # Create a client
    client = ftp_v1.CloudFtpClient()

    # Initialize request argument(s)
    user = ftp_v1.User()
    user.customer_service_account = "customer_service_account_value"
    user.user_credentials.credential_name = "credential_name_value"
    user.user_credentials.credential_type = "PUBLIC_KEY"
    user.storage_directory_mappings.bucket = "bucket_value"
    user.storage_directory_mappings.directory = "directory_value"
    user.storage_directory_mappings.permission = "READ_WRITE"

    request = ftp_v1.UpdateUserRequest(
        user=user,
    )

    # Make the request
    operation = client.update_user(request=request)

    print("Waiting for operation to complete...")

    response = operation.result()

    # Handle the response
    print(response)

Ruby

Para saber como instalar e usar a biblioteca de cliente do Cloud FTP, consulte Bibliotecas de cliente do Cloud FTP. Para mais informações, consulte a documentação de referência da APIRuby Cloud FTP.

Para se autenticar no Cloud FTP, configure o Application Default Credentials. Se quiser mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

require "google/cloud/ftp/v1"

##
# Snippet for the update_user call in the CloudFtp service
#
# This snippet has been automatically generated and should be regarded as a code
# template only. It will require modifications to work:
# - It may require correct/in-range values for request initialization.
# - It may require specifying regional endpoints when creating the service
# client as shown in https://cloud.google.com/ruby/docs/reference.
#
# This is an auto-generated example demonstrating basic usage of
# Google::Cloud::Ftp::V1::CloudFtp::Rest::Client#update_user.
#
def update_user
  # Create a client object. The client can be reused for multiple calls.
  client = Google::Cloud::Ftp::V1::CloudFtp::Rest::Client.new

  # Create a request. To set request fields, pass in keyword arguments.
  request = Google::Cloud::Ftp::V1::UpdateUserRequest.new

  # Call the update_user method.
  result = client.update_user request

  # The returned object is of type Gapic::Operation. You can use it to
  # check the status of an operation, cancel it, or wait for results.
  # Here is how to wait for a response.
  result.wait_until_done! timeout: 60
  if result.response?
    p result.response
  else
    puts "No response received."
  end
end