Skip to content

Commit 4b52aac

Browse files
feat: [google-cloud-storage-transfer] support Azure federated identity (#13943)
- [ ] Regenerate this pull request now. BEGIN_COMMIT_OVERRIDE feat: support Azure federated identity feat: support BYOSA docs: A comment for message `ObjectConditions` is changed docs: A comment for field `list_url` in message `.google.storagetransfer.v1.HttpData` is changed docs: A comment for field `overwrite_objects_already_existing_in_sink` in message `.google.storagetransfer.v1.TransferOptions` is changed docs: A comment for field `end_time_of_day` in message `.google.storagetransfer.v1.Schedule` is changed docs: A comment for enum value `COPY` in enum `LoggableAction` is changed END_COMMIT_OVERRIDE PiperOrigin-RevId: 762602696 Source-Link: googleapis/googleapis@bbeb053 Source-Link: googleapis/googleapis-gen@449fe07 Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLWNsb3VkLXN0b3JhZ2UtdHJhbnNmZXIvLk93bEJvdC55YW1sIiwiaCI6IjQ0OWZlMDdjMmEwMDg5NzQwNWRjYzBkNDdjMmM3YjYxZTUzMjg0MGQifQ== --------- Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
1 parent 82a928a commit 4b52aac

File tree

2 files changed

+113
-7
lines changed

2 files changed

+113
-7
lines changed

packages/google-cloud-storage-transfer/google/cloud/storage_transfer_v1/types/transfer_types.py

Lines changed: 87 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,13 @@ class ObjectConditions(proto.Message):
136136
field of S3 objects, and the ``Last-Modified`` header of Azure
137137
blobs.
138138
139+
For S3 objects, the ``LastModified`` value is the time the object
140+
begins uploading. If the object meets your "last modification time"
141+
criteria, but has not finished uploading, the object is not
142+
transferred. See `Transfer from Amazon S3 to Cloud
143+
Storage <https://cloud.google.com/storage-transfer/docs/create-transfers/agentless/s3#transfer_options>`__
144+
for more information.
145+
139146
Transfers with a
140147
[PosixFilesystem][google.storagetransfer.v1.PosixFilesystem] source
141148
or destination don't support ``ObjectConditions``.
@@ -499,8 +506,48 @@ class AzureBlobStorageData(proto.Message):
499506
[azure_credentials][google.storagetransfer.v1.AzureBlobStorageData.azure_credentials].
500507
501508
Format: ``projects/{project_number}/secrets/{secret_name}``
509+
federated_identity_config (google.cloud.storage_transfer_v1.types.AzureBlobStorageData.FederatedIdentityConfig):
510+
Optional. Federated identity config of a user registered
511+
Azure application.
512+
513+
If ``federated_identity_config`` is specified, do not
514+
specify
515+
[azure_credentials][google.storagetransfer.v1.AzureBlobStorageData.azure_credentials]
516+
or
517+
[credentials_secret][google.storagetransfer.v1.AzureBlobStorageData.credentials_secret].
502518
"""
503519

520+
class FederatedIdentityConfig(proto.Message):
521+
r"""The identity of an Azure application through which Storage Transfer
522+
Service can authenticate requests using Azure workload identity
523+
federation.
524+
525+
Storage Transfer Service can issue requests to Azure Storage through
526+
registered Azure applications, eliminating the need to pass
527+
credentials to Storage Transfer Service directly.
528+
529+
To configure federated identity, see `Configure access to Microsoft
530+
Azure
531+
Storage <https://cloud.google.com/storage-transfer/docs/source-microsoft-azure#option_3_authenticate_using_federated_identity>`__.
532+
533+
Attributes:
534+
client_id (str):
535+
Required. The client (application) ID of the
536+
application with federated credentials.
537+
tenant_id (str):
538+
Required. The tenant (directory) ID of the
539+
application with federated credentials.
540+
"""
541+
542+
client_id: str = proto.Field(
543+
proto.STRING,
544+
number=1,
545+
)
546+
tenant_id: str = proto.Field(
547+
proto.STRING,
548+
number=2,
549+
)
550+
504551
storage_account: str = proto.Field(
505552
proto.STRING,
506553
number=1,
@@ -522,6 +569,11 @@ class AzureBlobStorageData(proto.Message):
522569
proto.STRING,
523570
number=7,
524571
)
572+
federated_identity_config: FederatedIdentityConfig = proto.Field(
573+
proto.MESSAGE,
574+
number=8,
575+
message=FederatedIdentityConfig,
576+
)
525577

526578

527579
class HttpData(proto.Message):
@@ -568,10 +620,11 @@ class HttpData(proto.Message):
568620
569621
Attributes:
570622
list_url (str):
571-
Required. The URL that points to the file
572-
that stores the object list entries. This file
573-
must allow public access. Currently, only URLs
574-
with HTTP and HTTPS schemes are supported.
623+
Required. The URL that points to the file that stores the
624+
object list entries. This file must allow public access. The
625+
URL is either an HTTP/HTTPS address (e.g.
626+
``https://example.com/urllist.tsv``) or a Cloud Storage path
627+
(e.g. ``gs://my-bucket/urllist.tsv``).
575628
"""
576629

577630
list_url: str = proto.Field(
@@ -868,7 +921,7 @@ class TransferOptions(proto.Message):
868921
When to overwrite objects that already exist
869922
in the sink. The default is that only objects
870923
that are different from the source are
871-
ovewritten. If true, all objects in the sink
924+
overwritten. If true, all objects in the sink
872925
whose name matches an object in the source are
873926
overwritten with the source object.
874927
delete_objects_unique_in_sink (bool):
@@ -1529,7 +1582,7 @@ class Schedule(proto.Message):
15291582
``end_time_of_day`` specifies the end date and time for
15301583
starting new transfer operations. This field must be greater
15311584
than or equal to the timestamp corresponding to the
1532-
combintation of
1585+
combination of
15331586
[schedule_start_date][google.storagetransfer.v1.Schedule.schedule_start_date]
15341587
and
15351588
[start_time_of_day][google.storagetransfer.v1.Schedule.start_time_of_day],
@@ -1659,6 +1712,24 @@ class TransferJob(proto.Message):
16591712
project_id (str):
16601713
The ID of the Google Cloud project that owns
16611714
the job.
1715+
service_account (str):
1716+
Optional. The user-managed service account to which to
1717+
delegate service agent permissions. You can grant Cloud
1718+
Storage bucket permissions to this service account instead
1719+
of to the Transfer Service service agent.
1720+
1721+
Format is
1722+
``projects/-/serviceAccounts/ACCOUNT_EMAIL_OR_UNIQUEID``
1723+
1724+
Either the service account email
1725+
(``SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com``)
1726+
or the unique ID (``123456789012345678901``) are accepted in
1727+
the string. The ``-`` wildcard character is required;
1728+
replacing it with a project ID is invalid.
1729+
1730+
See
1731+
https://cloud.google.com//storage-transfer/docs/delegate-service-agent-permissions
1732+
for required permissions.
16621733
transfer_spec (google.cloud.storage_transfer_v1.types.TransferSpec):
16631734
Transfer specification.
16641735
replication_spec (google.cloud.storage_transfer_v1.types.ReplicationSpec):
@@ -1740,6 +1811,10 @@ class Status(proto.Enum):
17401811
proto.STRING,
17411812
number=3,
17421813
)
1814+
service_account: str = proto.Field(
1815+
proto.STRING,
1816+
number=18,
1817+
)
17431818
transfer_spec: "TransferSpec" = proto.Field(
17441819
proto.MESSAGE,
17451820
number=4,
@@ -2162,7 +2237,7 @@ class LoggableAction(proto.Enum):
21622237
Deleting objects at the source or the
21632238
destination.
21642239
COPY (3):
2165-
Copying objects to Google Cloud Storage.
2240+
Copying objects to the destination.
21662241
"""
21672242
LOGGABLE_ACTION_UNSPECIFIED = 0
21682243
FIND = 1
@@ -2183,10 +2258,15 @@ class LoggableActionState(proto.Enum):
21832258
``LoggableAction`` terminated in an error state. ``FAILED``
21842259
actions are logged as
21852260
[ERROR][google.logging.type.LogSeverity.ERROR].
2261+
SKIPPED (3):
2262+
The ``COPY`` action was skipped for this file. Only
2263+
supported for agent-based transfers. ``SKIPPED`` actions are
2264+
logged as [INFO][google.logging.type.LogSeverity.INFO].
21862265
"""
21872266
LOGGABLE_ACTION_STATE_UNSPECIFIED = 0
21882267
SUCCEEDED = 1
21892268
FAILED = 2
2269+
SKIPPED = 3
21902270

21912271
log_actions: MutableSequence[LoggableAction] = proto.RepeatedField(
21922272
proto.ENUM,

packages/google-cloud-storage-transfer/tests/unit/gapic/storage_transfer_v1/test_storage_transfer_service.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,6 +1477,7 @@ def test_create_transfer_job(request_type, transport: str = "grpc"):
14771477
name="name_value",
14781478
description="description_value",
14791479
project_id="project_id_value",
1480+
service_account="service_account_value",
14801481
status=transfer_types.TransferJob.Status.ENABLED,
14811482
latest_operation_name="latest_operation_name_value",
14821483
)
@@ -1493,6 +1494,7 @@ def test_create_transfer_job(request_type, transport: str = "grpc"):
14931494
assert response.name == "name_value"
14941495
assert response.description == "description_value"
14951496
assert response.project_id == "project_id_value"
1497+
assert response.service_account == "service_account_value"
14961498
assert response.status == transfer_types.TransferJob.Status.ENABLED
14971499
assert response.latest_operation_name == "latest_operation_name_value"
14981500

@@ -1627,6 +1629,7 @@ async def test_create_transfer_job_async(
16271629
name="name_value",
16281630
description="description_value",
16291631
project_id="project_id_value",
1632+
service_account="service_account_value",
16301633
status=transfer_types.TransferJob.Status.ENABLED,
16311634
latest_operation_name="latest_operation_name_value",
16321635
)
@@ -1644,6 +1647,7 @@ async def test_create_transfer_job_async(
16441647
assert response.name == "name_value"
16451648
assert response.description == "description_value"
16461649
assert response.project_id == "project_id_value"
1650+
assert response.service_account == "service_account_value"
16471651
assert response.status == transfer_types.TransferJob.Status.ENABLED
16481652
assert response.latest_operation_name == "latest_operation_name_value"
16491653

@@ -1679,6 +1683,7 @@ def test_update_transfer_job(request_type, transport: str = "grpc"):
16791683
name="name_value",
16801684
description="description_value",
16811685
project_id="project_id_value",
1686+
service_account="service_account_value",
16821687
status=transfer_types.TransferJob.Status.ENABLED,
16831688
latest_operation_name="latest_operation_name_value",
16841689
)
@@ -1695,6 +1700,7 @@ def test_update_transfer_job(request_type, transport: str = "grpc"):
16951700
assert response.name == "name_value"
16961701
assert response.description == "description_value"
16971702
assert response.project_id == "project_id_value"
1703+
assert response.service_account == "service_account_value"
16981704
assert response.status == transfer_types.TransferJob.Status.ENABLED
16991705
assert response.latest_operation_name == "latest_operation_name_value"
17001706

@@ -1835,6 +1841,7 @@ async def test_update_transfer_job_async(
18351841
name="name_value",
18361842
description="description_value",
18371843
project_id="project_id_value",
1844+
service_account="service_account_value",
18381845
status=transfer_types.TransferJob.Status.ENABLED,
18391846
latest_operation_name="latest_operation_name_value",
18401847
)
@@ -1852,6 +1859,7 @@ async def test_update_transfer_job_async(
18521859
assert response.name == "name_value"
18531860
assert response.description == "description_value"
18541861
assert response.project_id == "project_id_value"
1862+
assert response.service_account == "service_account_value"
18551863
assert response.status == transfer_types.TransferJob.Status.ENABLED
18561864
assert response.latest_operation_name == "latest_operation_name_value"
18571865

@@ -1950,6 +1958,7 @@ def test_get_transfer_job(request_type, transport: str = "grpc"):
19501958
name="name_value",
19511959
description="description_value",
19521960
project_id="project_id_value",
1961+
service_account="service_account_value",
19531962
status=transfer_types.TransferJob.Status.ENABLED,
19541963
latest_operation_name="latest_operation_name_value",
19551964
)
@@ -1966,6 +1975,7 @@ def test_get_transfer_job(request_type, transport: str = "grpc"):
19661975
assert response.name == "name_value"
19671976
assert response.description == "description_value"
19681977
assert response.project_id == "project_id_value"
1978+
assert response.service_account == "service_account_value"
19691979
assert response.status == transfer_types.TransferJob.Status.ENABLED
19701980
assert response.latest_operation_name == "latest_operation_name_value"
19711981

@@ -2100,6 +2110,7 @@ async def test_get_transfer_job_async(
21002110
name="name_value",
21012111
description="description_value",
21022112
project_id="project_id_value",
2113+
service_account="service_account_value",
21032114
status=transfer_types.TransferJob.Status.ENABLED,
21042115
latest_operation_name="latest_operation_name_value",
21052116
)
@@ -2117,6 +2128,7 @@ async def test_get_transfer_job_async(
21172128
assert response.name == "name_value"
21182129
assert response.description == "description_value"
21192130
assert response.project_id == "project_id_value"
2131+
assert response.service_account == "service_account_value"
21202132
assert response.status == transfer_types.TransferJob.Status.ENABLED
21212133
assert response.latest_operation_name == "latest_operation_name_value"
21222134

@@ -8207,6 +8219,7 @@ async def test_create_transfer_job_empty_call_grpc_asyncio():
82078219
name="name_value",
82088220
description="description_value",
82098221
project_id="project_id_value",
8222+
service_account="service_account_value",
82108223
status=transfer_types.TransferJob.Status.ENABLED,
82118224
latest_operation_name="latest_operation_name_value",
82128225
)
@@ -8240,6 +8253,7 @@ async def test_update_transfer_job_empty_call_grpc_asyncio():
82408253
name="name_value",
82418254
description="description_value",
82428255
project_id="project_id_value",
8256+
service_account="service_account_value",
82438257
status=transfer_types.TransferJob.Status.ENABLED,
82448258
latest_operation_name="latest_operation_name_value",
82458259
)
@@ -8271,6 +8285,7 @@ async def test_get_transfer_job_empty_call_grpc_asyncio():
82718285
name="name_value",
82728286
description="description_value",
82738287
project_id="project_id_value",
8288+
service_account="service_account_value",
82748289
status=transfer_types.TransferJob.Status.ENABLED,
82758290
latest_operation_name="latest_operation_name_value",
82768291
)
@@ -8744,6 +8759,7 @@ def test_create_transfer_job_rest_call_success(request_type):
87448759
"name": "name_value",
87458760
"description": "description_value",
87468761
"project_id": "project_id_value",
8762+
"service_account": "service_account_value",
87478763
"transfer_spec": {
87488764
"gcs_data_sink": {
87498765
"bucket_name": "bucket_name_value",
@@ -8772,6 +8788,10 @@ def test_create_transfer_job_rest_call_success(request_type):
87728788
"container": "container_value",
87738789
"path": "path_value",
87748790
"credentials_secret": "credentials_secret_value",
8791+
"federated_identity_config": {
8792+
"client_id": "client_id_value",
8793+
"tenant_id": "tenant_id_value",
8794+
},
87758795
},
87768796
"aws_s3_compatible_data_source": {
87778797
"bucket_name": "bucket_name_value",
@@ -8940,6 +8960,7 @@ def get_message_fields(field):
89408960
name="name_value",
89418961
description="description_value",
89428962
project_id="project_id_value",
8963+
service_account="service_account_value",
89438964
status=transfer_types.TransferJob.Status.ENABLED,
89448965
latest_operation_name="latest_operation_name_value",
89458966
)
@@ -8961,6 +8982,7 @@ def get_message_fields(field):
89618982
assert response.name == "name_value"
89628983
assert response.description == "description_value"
89638984
assert response.project_id == "project_id_value"
8985+
assert response.service_account == "service_account_value"
89648986
assert response.status == transfer_types.TransferJob.Status.ENABLED
89658987
assert response.latest_operation_name == "latest_operation_name_value"
89668988

@@ -9076,6 +9098,7 @@ def test_update_transfer_job_rest_call_success(request_type):
90769098
name="name_value",
90779099
description="description_value",
90789100
project_id="project_id_value",
9101+
service_account="service_account_value",
90799102
status=transfer_types.TransferJob.Status.ENABLED,
90809103
latest_operation_name="latest_operation_name_value",
90819104
)
@@ -9097,6 +9120,7 @@ def test_update_transfer_job_rest_call_success(request_type):
90979120
assert response.name == "name_value"
90989121
assert response.description == "description_value"
90999122
assert response.project_id == "project_id_value"
9123+
assert response.service_account == "service_account_value"
91009124
assert response.status == transfer_types.TransferJob.Status.ENABLED
91019125
assert response.latest_operation_name == "latest_operation_name_value"
91029126

@@ -9210,6 +9234,7 @@ def test_get_transfer_job_rest_call_success(request_type):
92109234
name="name_value",
92119235
description="description_value",
92129236
project_id="project_id_value",
9237+
service_account="service_account_value",
92139238
status=transfer_types.TransferJob.Status.ENABLED,
92149239
latest_operation_name="latest_operation_name_value",
92159240
)
@@ -9231,6 +9256,7 @@ def test_get_transfer_job_rest_call_success(request_type):
92319256
assert response.name == "name_value"
92329257
assert response.description == "description_value"
92339258
assert response.project_id == "project_id_value"
9259+
assert response.service_account == "service_account_value"
92349260
assert response.status == transfer_types.TransferJob.Status.ENABLED
92359261
assert response.latest_operation_name == "latest_operation_name_value"
92369262

0 commit comments

Comments
 (0)