google-apis-binaryauthorization_v1 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/google/apis/binaryauthorization_v1/classes.rb +630 -40
- data/lib/google/apis/binaryauthorization_v1/gem_version.rb +2 -2
- data/lib/google/apis/binaryauthorization_v1/representations.rb +251 -0
- data/lib/google/apis/binaryauthorization_v1/service.rb +188 -11
- metadata +4 -4
@@ -44,8 +44,8 @@ module Google
|
|
44
44
|
# image, in the format `projects/*/attestors/*`. Each attestor must exist before
|
45
45
|
# a policy can reference it. To add an attestor to a policy the principal
|
46
46
|
# issuing the policy change request must be able to read the attestor resource.
|
47
|
-
# Note: this field must be non-empty when the evaluation_mode field specifies
|
48
|
-
# REQUIRE_ATTESTATION
|
47
|
+
# Note: this field must be non-empty when the `evaluation_mode` field specifies `
|
48
|
+
# REQUIRE_ATTESTATION`, otherwise it must be empty.
|
49
49
|
# Corresponds to the JSON property `requireAttestationsBy`
|
50
50
|
# @return [Array<String>]
|
51
51
|
attr_accessor :require_attestations_by
|
@@ -84,6 +84,42 @@ module Google
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
+
# An attestation authenticator that will be used to verify attestations.
|
88
|
+
# Typically this is just a set of public keys. Conceptually, an authenticator
|
89
|
+
# can be treated as always returning either "authenticated" or "not
|
90
|
+
# authenticated" when presented with a signed attestation (almost always assumed
|
91
|
+
# to be a [DSSE](https://github.com/secure-systems-lab/dsse) attestation). The
|
92
|
+
# details of how an authenticator makes this decision are specific to the type
|
93
|
+
# of 'authenticator' that this message wraps.
|
94
|
+
class AttestationAuthenticator
|
95
|
+
include Google::Apis::Core::Hashable
|
96
|
+
|
97
|
+
# Optional. A user-provided name for this `AttestationAuthenticator`. This field
|
98
|
+
# has no effect on the policy evaluation behavior except to improve readability
|
99
|
+
# of messages in evaluation results.
|
100
|
+
# Corresponds to the JSON property `displayName`
|
101
|
+
# @return [String]
|
102
|
+
attr_accessor :display_name
|
103
|
+
|
104
|
+
# A bundle of PKIX public keys, used to authenticate attestation signatures.
|
105
|
+
# Generally, a signature is considered to be authenticated by a `
|
106
|
+
# PkixPublicKeySet` if any of the public keys verify it (i.e. it is an "OR" of
|
107
|
+
# the keys).
|
108
|
+
# Corresponds to the JSON property `pkixPublicKeySet`
|
109
|
+
# @return [Google::Apis::BinaryauthorizationV1::PkixPublicKeySet]
|
110
|
+
attr_accessor :pkix_public_key_set
|
111
|
+
|
112
|
+
def initialize(**args)
|
113
|
+
update!(**args)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Update properties of this object
|
117
|
+
def update!(**args)
|
118
|
+
@display_name = args[:display_name] if args.key?(:display_name)
|
119
|
+
@pkix_public_key_set = args[:pkix_public_key_set] if args.key?(:pkix_public_key_set)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
87
123
|
# Occurrence that represents a single "attestation". The authenticity of an
|
88
124
|
# attestation can be verified using the attached signature. If the verifier
|
89
125
|
# trusts the public key of the signer, then verifying the signature is
|
@@ -131,6 +167,26 @@ module Google
|
|
131
167
|
end
|
132
168
|
end
|
133
169
|
|
170
|
+
# Specifies the locations for fetching the provenance attestations.
|
171
|
+
class AttestationSource
|
172
|
+
include Google::Apis::Core::Hashable
|
173
|
+
|
174
|
+
# The IDs of the GCP projects storing the SLSA attestations as Container
|
175
|
+
# Analysis Occurrences.
|
176
|
+
# Corresponds to the JSON property `containerAnalysisAttestationProjects`
|
177
|
+
# @return [Array<String>]
|
178
|
+
attr_accessor :container_analysis_attestation_projects
|
179
|
+
|
180
|
+
def initialize(**args)
|
181
|
+
update!(**args)
|
182
|
+
end
|
183
|
+
|
184
|
+
# Update properties of this object
|
185
|
+
def update!(**args)
|
186
|
+
@container_analysis_attestation_projects = args[:container_analysis_attestation_projects] if args.key?(:container_analysis_attestation_projects)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
134
190
|
# An attestor that attests to container image artifacts. An existing attestor
|
135
191
|
# cannot be modified except where indicated.
|
136
192
|
class Attestor
|
@@ -187,10 +243,11 @@ module Google
|
|
187
243
|
|
188
244
|
# ASCII-armored representation of a PGP public key, as the entire output by the
|
189
245
|
# command `gpg --export --armor foo@example.com` (either LF or CRLF line endings)
|
190
|
-
# . When using this field, `id` should be left blank. The
|
191
|
-
# will calculate the ID and fill it in automatically.
|
192
|
-
# as the OpenPGP RFC4880 V4 fingerprint,
|
193
|
-
# is provided by the caller, it will be
|
246
|
+
# . When using this field, `id` should be left blank. The Binary Authorization
|
247
|
+
# API handlers will calculate the ID and fill it in automatically. Binary
|
248
|
+
# Authorization computes this ID as the OpenPGP RFC4880 V4 fingerprint,
|
249
|
+
# represented as upper-case hex. If `id` is provided by the caller, it will be
|
250
|
+
# overwritten by the API-calculated ID.
|
194
251
|
# Corresponds to the JSON property `asciiArmoredPgpPublicKey`
|
195
252
|
# @return [String]
|
196
253
|
attr_accessor :ascii_armored_pgp_public_key
|
@@ -200,18 +257,18 @@ module Google
|
|
200
257
|
# @return [String]
|
201
258
|
attr_accessor :comment
|
202
259
|
|
203
|
-
# The ID of this public key. Signatures verified by
|
204
|
-
# of the public key that can be used to verify them, and that ID
|
205
|
-
# contents of this field exactly. Additional restrictions on this
|
206
|
-
# imposed based on which public key type is encapsulated. See the
|
207
|
-
# on `public_key` cases below for details.
|
260
|
+
# The ID of this public key. Signatures verified by Binary Authorization must
|
261
|
+
# include the ID of the public key that can be used to verify them, and that ID
|
262
|
+
# must match the contents of this field exactly. Additional restrictions on this
|
263
|
+
# field can be imposed based on which public key type is encapsulated. See the
|
264
|
+
# documentation on `public_key` cases below for details.
|
208
265
|
# Corresponds to the JSON property `id`
|
209
266
|
# @return [String]
|
210
267
|
attr_accessor :id
|
211
268
|
|
212
|
-
# A public key in the PkixPublicKey format
|
213
|
-
#
|
214
|
-
#
|
269
|
+
# A public key in the PkixPublicKey [format](https://tools.ietf.org/html/rfc5280#
|
270
|
+
# section-4.1.2.7). Public keys of this type are typically textually encoded
|
271
|
+
# using the PEM format.
|
215
272
|
# Corresponds to the JSON property `pkixPublicKey`
|
216
273
|
# @return [Google::Apis::BinaryauthorizationV1::PkixPublicKey]
|
217
274
|
attr_accessor :pkix_public_key
|
@@ -305,6 +362,124 @@ module Google
|
|
305
362
|
end
|
306
363
|
end
|
307
364
|
|
365
|
+
# A single check to perform against a Pod. Checks are grouped into `CheckSet`
|
366
|
+
# objects, which are defined by the top-level policy.
|
367
|
+
class Check
|
368
|
+
include Google::Apis::Core::Hashable
|
369
|
+
|
370
|
+
# Optional. A special-case check that always denies. Note that this still only
|
371
|
+
# applies when the scope of the `CheckSet` applies and the image isn't exempted
|
372
|
+
# by an image allowlist. This check is primarily useful for testing, or to set
|
373
|
+
# the default behavior for all unmatched scopes to "deny".
|
374
|
+
# Corresponds to the JSON property `alwaysDeny`
|
375
|
+
# @return [Boolean]
|
376
|
+
attr_accessor :always_deny
|
377
|
+
alias_method :always_deny?, :always_deny
|
378
|
+
|
379
|
+
# Optional. A user-provided name for this check. This field has no effect on the
|
380
|
+
# policy evaluation behavior except to improve readability of messages in
|
381
|
+
# evaluation results.
|
382
|
+
# Corresponds to the JSON property `displayName`
|
383
|
+
# @return [String]
|
384
|
+
attr_accessor :display_name
|
385
|
+
|
386
|
+
# Images that are exempted from normal checks based on name pattern only.
|
387
|
+
# Corresponds to the JSON property `imageAllowlist`
|
388
|
+
# @return [Google::Apis::BinaryauthorizationV1::ImageAllowlist]
|
389
|
+
attr_accessor :image_allowlist
|
390
|
+
|
391
|
+
# An image freshness check, which rejects images that were uploaded before the
|
392
|
+
# set number of days ago to the supported repositories.
|
393
|
+
# Corresponds to the JSON property `imageFreshnessCheck`
|
394
|
+
# @return [Google::Apis::BinaryauthorizationV1::ImageFreshnessCheck]
|
395
|
+
attr_accessor :image_freshness_check
|
396
|
+
|
397
|
+
# Require a signed [DSSE](https://github.com/secure-systems-lab/dsse)
|
398
|
+
# attestation with type SimpleSigning.
|
399
|
+
# Corresponds to the JSON property `simpleSigningAttestationCheck`
|
400
|
+
# @return [Google::Apis::BinaryauthorizationV1::SimpleSigningAttestationCheck]
|
401
|
+
attr_accessor :simple_signing_attestation_check
|
402
|
+
|
403
|
+
# A SLSA provenance attestation check, which ensures that images are built by a
|
404
|
+
# trusted builder using source code from its trusted repositories only.
|
405
|
+
# Corresponds to the JSON property `slsaCheck`
|
406
|
+
# @return [Google::Apis::BinaryauthorizationV1::SlsaCheck]
|
407
|
+
attr_accessor :slsa_check
|
408
|
+
|
409
|
+
# A trusted directory check, which rejects images that do not come from the set
|
410
|
+
# of user-configured trusted directories.
|
411
|
+
# Corresponds to the JSON property `trustedDirectoryCheck`
|
412
|
+
# @return [Google::Apis::BinaryauthorizationV1::TrustedDirectoryCheck]
|
413
|
+
attr_accessor :trusted_directory_check
|
414
|
+
|
415
|
+
# An image vulnerability check, which rejects images that violate the configured
|
416
|
+
# vulnerability rules.
|
417
|
+
# Corresponds to the JSON property `vulnerabilityCheck`
|
418
|
+
# @return [Google::Apis::BinaryauthorizationV1::VulnerabilityCheck]
|
419
|
+
attr_accessor :vulnerability_check
|
420
|
+
|
421
|
+
def initialize(**args)
|
422
|
+
update!(**args)
|
423
|
+
end
|
424
|
+
|
425
|
+
# Update properties of this object
|
426
|
+
def update!(**args)
|
427
|
+
@always_deny = args[:always_deny] if args.key?(:always_deny)
|
428
|
+
@display_name = args[:display_name] if args.key?(:display_name)
|
429
|
+
@image_allowlist = args[:image_allowlist] if args.key?(:image_allowlist)
|
430
|
+
@image_freshness_check = args[:image_freshness_check] if args.key?(:image_freshness_check)
|
431
|
+
@simple_signing_attestation_check = args[:simple_signing_attestation_check] if args.key?(:simple_signing_attestation_check)
|
432
|
+
@slsa_check = args[:slsa_check] if args.key?(:slsa_check)
|
433
|
+
@trusted_directory_check = args[:trusted_directory_check] if args.key?(:trusted_directory_check)
|
434
|
+
@vulnerability_check = args[:vulnerability_check] if args.key?(:vulnerability_check)
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
# A conjunction of policy checks, scoped to a particular namespace or Kubernetes
|
439
|
+
# service account. In order for evaluation of a `CheckSet` to return "allowed"
|
440
|
+
# for a given image in a given Pod, one of the following conditions must be
|
441
|
+
# satisfied: * The image is explicitly exempted by an entry in `image_allowlist`,
|
442
|
+
# OR * ALL of the `checks` evaluate to "allowed".
|
443
|
+
class CheckSet
|
444
|
+
include Google::Apis::Core::Hashable
|
445
|
+
|
446
|
+
# Optional. The checks to apply. The ultimate result of evaluating the check set
|
447
|
+
# will be "allow" if and only if every check in `checks` evaluates to "allow".
|
448
|
+
# If `checks` is empty, the default behavior is "always allow".
|
449
|
+
# Corresponds to the JSON property `checks`
|
450
|
+
# @return [Array<Google::Apis::BinaryauthorizationV1::Check>]
|
451
|
+
attr_accessor :checks
|
452
|
+
|
453
|
+
# Optional. A user-provided name for this `CheckSet`. This field has no effect
|
454
|
+
# on the policy evaluation behavior except to improve readability of messages in
|
455
|
+
# evaluation results.
|
456
|
+
# Corresponds to the JSON property `displayName`
|
457
|
+
# @return [String]
|
458
|
+
attr_accessor :display_name
|
459
|
+
|
460
|
+
# Images that are exempted from normal checks based on name pattern only.
|
461
|
+
# Corresponds to the JSON property `imageAllowlist`
|
462
|
+
# @return [Google::Apis::BinaryauthorizationV1::ImageAllowlist]
|
463
|
+
attr_accessor :image_allowlist
|
464
|
+
|
465
|
+
# A scope specifier for `CheckSet` objects.
|
466
|
+
# Corresponds to the JSON property `scope`
|
467
|
+
# @return [Google::Apis::BinaryauthorizationV1::Scope]
|
468
|
+
attr_accessor :scope
|
469
|
+
|
470
|
+
def initialize(**args)
|
471
|
+
update!(**args)
|
472
|
+
end
|
473
|
+
|
474
|
+
# Update properties of this object
|
475
|
+
def update!(**args)
|
476
|
+
@checks = args[:checks] if args.key?(:checks)
|
477
|
+
@display_name = args[:display_name] if args.key?(:display_name)
|
478
|
+
@image_allowlist = args[:image_allowlist] if args.key?(:image_allowlist)
|
479
|
+
@scope = args[:scope] if args.key?(:scope)
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
308
483
|
# A generic empty message that you can re-use to avoid defining duplicated empty
|
309
484
|
# messages in your APIs. A typical example is to use it as the request or the
|
310
485
|
# response type of an API method. For instance: service Foo ` rpc Bar(google.
|
@@ -375,6 +550,47 @@ module Google
|
|
375
550
|
end
|
376
551
|
end
|
377
552
|
|
553
|
+
# A Binary Authorization policy for a GKE cluster. This is one type of policy
|
554
|
+
# that can occur as a `PlatformPolicy`.
|
555
|
+
class GkePolicy
|
556
|
+
include Google::Apis::Core::Hashable
|
557
|
+
|
558
|
+
# Optional. The `CheckSet` objects to apply, scoped by namespace or namespace
|
559
|
+
# and service account. Exactly one `CheckSet` will be evaluated for a given Pod (
|
560
|
+
# unless the list is empty, in which case the behavior is "always allow"). If
|
561
|
+
# multiple `CheckSet` objects have scopes that match the namespace and service
|
562
|
+
# account of the Pod being evaluated, only the `CheckSet` with the MOST SPECIFIC
|
563
|
+
# scope will match. `CheckSet` objects must be listed in order of decreasing
|
564
|
+
# specificity, i.e. if a scope matches a given service account (which must
|
565
|
+
# include the namespace), it must come before a `CheckSet` with a scope matching
|
566
|
+
# just that namespace. This property is enforced by server-side validation. The
|
567
|
+
# purpose of this restriction is to ensure that if more than one `CheckSet`
|
568
|
+
# matches a given Pod, the `CheckSet` that will be evaluated will always be the
|
569
|
+
# first in the list to match (because if any other matches, it must be less
|
570
|
+
# specific). If `check_sets` is empty, the default behavior is to allow all
|
571
|
+
# images. If `check_sets` is non-empty, the last `check_sets` entry must always
|
572
|
+
# be a `CheckSet` with no scope set, i.e. a catchall to handle any situation not
|
573
|
+
# caught by the preceding `CheckSet` objects.
|
574
|
+
# Corresponds to the JSON property `checkSets`
|
575
|
+
# @return [Array<Google::Apis::BinaryauthorizationV1::CheckSet>]
|
576
|
+
attr_accessor :check_sets
|
577
|
+
|
578
|
+
# Images that are exempted from normal checks based on name pattern only.
|
579
|
+
# Corresponds to the JSON property `imageAllowlist`
|
580
|
+
# @return [Google::Apis::BinaryauthorizationV1::ImageAllowlist]
|
581
|
+
attr_accessor :image_allowlist
|
582
|
+
|
583
|
+
def initialize(**args)
|
584
|
+
update!(**args)
|
585
|
+
end
|
586
|
+
|
587
|
+
# Update properties of this object
|
588
|
+
def update!(**args)
|
589
|
+
@check_sets = args[:check_sets] if args.key?(:check_sets)
|
590
|
+
@image_allowlist = args[:image_allowlist] if args.key?(:image_allowlist)
|
591
|
+
end
|
592
|
+
end
|
593
|
+
|
378
594
|
# An Identity and Access Management (IAM) policy, which specifies access
|
379
595
|
# controls for Google Cloud resources. A `Policy` is a collection of `bindings`.
|
380
596
|
# A `binding` binds one or more `members`, or principals, to a single `role`.
|
@@ -386,22 +602,22 @@ module Google
|
|
386
602
|
# evaluates to `true`. A condition can add constraints based on attributes of
|
387
603
|
# the request, the resource, or both. To learn which resources support
|
388
604
|
# conditions in their IAM policies, see the [IAM documentation](https://cloud.
|
389
|
-
# google.com/iam/help/conditions/resource-policies). **JSON example:** ` "
|
605
|
+
# google.com/iam/help/conditions/resource-policies). **JSON example:** ``` ` "
|
390
606
|
# bindings": [ ` "role": "roles/resourcemanager.organizationAdmin", "members": [
|
391
607
|
# "user:mike@example.com", "group:admins@example.com", "domain:google.com", "
|
392
608
|
# serviceAccount:my-project-id@appspot.gserviceaccount.com" ] `, ` "role": "
|
393
609
|
# roles/resourcemanager.organizationViewer", "members": [ "user:eve@example.com"
|
394
610
|
# ], "condition": ` "title": "expirable access", "description": "Does not grant
|
395
611
|
# access after Sep 2020", "expression": "request.time < timestamp('2020-10-01T00:
|
396
|
-
# 00:00.000Z')", ` ` ], "etag": "BwWWja0YfJA=", "version": 3 ` **YAML
|
397
|
-
# bindings: - members: - user:mike@example.com - group:admins@
|
398
|
-
# domain:google.com - serviceAccount:my-project-id@appspot.
|
399
|
-
# role: roles/resourcemanager.organizationAdmin - members: -
|
400
|
-
# com role: roles/resourcemanager.organizationViewer condition:
|
401
|
-
# access description: Does not grant access after Sep 2020
|
402
|
-
# time < timestamp('2020-10-01T00:00:00.000Z') etag:
|
403
|
-
# a description of IAM and its features, see the
|
404
|
-
# cloud.google.com/iam/docs/).
|
612
|
+
# 00:00.000Z')", ` ` ], "etag": "BwWWja0YfJA=", "version": 3 ` ``` **YAML
|
613
|
+
# example:** ``` bindings: - members: - user:mike@example.com - group:admins@
|
614
|
+
# example.com - domain:google.com - serviceAccount:my-project-id@appspot.
|
615
|
+
# gserviceaccount.com role: roles/resourcemanager.organizationAdmin - members: -
|
616
|
+
# user:eve@example.com role: roles/resourcemanager.organizationViewer condition:
|
617
|
+
# title: expirable access description: Does not grant access after Sep 2020
|
618
|
+
# expression: request.time < timestamp('2020-10-01T00:00:00.000Z') etag:
|
619
|
+
# BwWWja0YfJA= version: 3 ``` For a description of IAM and its features, see the
|
620
|
+
# [IAM documentation](https://cloud.google.com/iam/docs/).
|
405
621
|
class IamPolicy
|
406
622
|
include Google::Apis::Core::Hashable
|
407
623
|
|
@@ -464,6 +680,47 @@ module Google
|
|
464
680
|
end
|
465
681
|
end
|
466
682
|
|
683
|
+
# Images that are exempted from normal checks based on name pattern only.
|
684
|
+
class ImageAllowlist
|
685
|
+
include Google::Apis::Core::Hashable
|
686
|
+
|
687
|
+
# Required. A disjunction of image patterns to allow. If any of these patterns
|
688
|
+
# match, then the image is considered exempted by this allowlist.
|
689
|
+
# Corresponds to the JSON property `allowPattern`
|
690
|
+
# @return [Array<String>]
|
691
|
+
attr_accessor :allow_pattern
|
692
|
+
|
693
|
+
def initialize(**args)
|
694
|
+
update!(**args)
|
695
|
+
end
|
696
|
+
|
697
|
+
# Update properties of this object
|
698
|
+
def update!(**args)
|
699
|
+
@allow_pattern = args[:allow_pattern] if args.key?(:allow_pattern)
|
700
|
+
end
|
701
|
+
end
|
702
|
+
|
703
|
+
# An image freshness check, which rejects images that were uploaded before the
|
704
|
+
# set number of days ago to the supported repositories.
|
705
|
+
class ImageFreshnessCheck
|
706
|
+
include Google::Apis::Core::Hashable
|
707
|
+
|
708
|
+
# Required. The max number of days that is allowed since the image was uploaded.
|
709
|
+
# Must be greater than zero.
|
710
|
+
# Corresponds to the JSON property `maxUploadAgeDays`
|
711
|
+
# @return [Fixnum]
|
712
|
+
attr_accessor :max_upload_age_days
|
713
|
+
|
714
|
+
def initialize(**args)
|
715
|
+
update!(**args)
|
716
|
+
end
|
717
|
+
|
718
|
+
# Update properties of this object
|
719
|
+
def update!(**args)
|
720
|
+
@max_upload_age_days = args[:max_upload_age_days] if args.key?(:max_upload_age_days)
|
721
|
+
end
|
722
|
+
end
|
723
|
+
|
467
724
|
#
|
468
725
|
class Jwt
|
469
726
|
include Google::Apis::Core::Hashable
|
@@ -485,7 +742,7 @@ module Google
|
|
485
742
|
end
|
486
743
|
end
|
487
744
|
|
488
|
-
# Response message for
|
745
|
+
# Response message for BinauthzManagementServiceV1.ListAttestors.
|
489
746
|
class ListAttestorsResponse
|
490
747
|
include Google::Apis::Core::Hashable
|
491
748
|
|
@@ -512,9 +769,36 @@ module Google
|
|
512
769
|
end
|
513
770
|
end
|
514
771
|
|
515
|
-
#
|
516
|
-
|
517
|
-
|
772
|
+
# Response message for PlatformPolicyManagementService.ListPlatformPolicies.
|
773
|
+
class ListPlatformPoliciesResponse
|
774
|
+
include Google::Apis::Core::Hashable
|
775
|
+
|
776
|
+
# A token to retrieve the next page of results. Pass this value in the
|
777
|
+
# ListPlatformPoliciesRequest.page_token field in the subsequent call to the `
|
778
|
+
# ListPlatformPolicies` method to retrieve the next page of results.
|
779
|
+
# Corresponds to the JSON property `nextPageToken`
|
780
|
+
# @return [String]
|
781
|
+
attr_accessor :next_page_token
|
782
|
+
|
783
|
+
# The list of platform policies.
|
784
|
+
# Corresponds to the JSON property `platformPolicies`
|
785
|
+
# @return [Array<Google::Apis::BinaryauthorizationV1::PlatformPolicy>]
|
786
|
+
attr_accessor :platform_policies
|
787
|
+
|
788
|
+
def initialize(**args)
|
789
|
+
update!(**args)
|
790
|
+
end
|
791
|
+
|
792
|
+
# Update properties of this object
|
793
|
+
def update!(**args)
|
794
|
+
@next_page_token = args[:next_page_token] if args.key?(:next_page_token)
|
795
|
+
@platform_policies = args[:platform_policies] if args.key?(:platform_policies)
|
796
|
+
end
|
797
|
+
end
|
798
|
+
|
799
|
+
# A public key in the PkixPublicKey [format](https://tools.ietf.org/html/rfc5280#
|
800
|
+
# section-4.1.2.7). Public keys of this type are typically textually encoded
|
801
|
+
# using the PEM format.
|
518
802
|
class PkixPublicKey
|
519
803
|
include Google::Apis::Core::Hashable
|
520
804
|
|
@@ -543,6 +827,67 @@ module Google
|
|
543
827
|
end
|
544
828
|
end
|
545
829
|
|
830
|
+
# A bundle of PKIX public keys, used to authenticate attestation signatures.
|
831
|
+
# Generally, a signature is considered to be authenticated by a `
|
832
|
+
# PkixPublicKeySet` if any of the public keys verify it (i.e. it is an "OR" of
|
833
|
+
# the keys).
|
834
|
+
class PkixPublicKeySet
|
835
|
+
include Google::Apis::Core::Hashable
|
836
|
+
|
837
|
+
# Required. `pkix_public_keys` must have at least one entry.
|
838
|
+
# Corresponds to the JSON property `pkixPublicKeys`
|
839
|
+
# @return [Array<Google::Apis::BinaryauthorizationV1::PkixPublicKey>]
|
840
|
+
attr_accessor :pkix_public_keys
|
841
|
+
|
842
|
+
def initialize(**args)
|
843
|
+
update!(**args)
|
844
|
+
end
|
845
|
+
|
846
|
+
# Update properties of this object
|
847
|
+
def update!(**args)
|
848
|
+
@pkix_public_keys = args[:pkix_public_keys] if args.key?(:pkix_public_keys)
|
849
|
+
end
|
850
|
+
end
|
851
|
+
|
852
|
+
# A Binary Authorization platform policy for deployments on various platforms.
|
853
|
+
class PlatformPolicy
|
854
|
+
include Google::Apis::Core::Hashable
|
855
|
+
|
856
|
+
# Optional. A description comment about the policy.
|
857
|
+
# Corresponds to the JSON property `description`
|
858
|
+
# @return [String]
|
859
|
+
attr_accessor :description
|
860
|
+
|
861
|
+
# A Binary Authorization policy for a GKE cluster. This is one type of policy
|
862
|
+
# that can occur as a `PlatformPolicy`.
|
863
|
+
# Corresponds to the JSON property `gkePolicy`
|
864
|
+
# @return [Google::Apis::BinaryauthorizationV1::GkePolicy]
|
865
|
+
attr_accessor :gke_policy
|
866
|
+
|
867
|
+
# Output only. The relative resource name of the Binary Authorization platform
|
868
|
+
# policy, in the form of `projects/*/platforms/*/policies/*`.
|
869
|
+
# Corresponds to the JSON property `name`
|
870
|
+
# @return [String]
|
871
|
+
attr_accessor :name
|
872
|
+
|
873
|
+
# Output only. Time when the policy was last updated.
|
874
|
+
# Corresponds to the JSON property `updateTime`
|
875
|
+
# @return [String]
|
876
|
+
attr_accessor :update_time
|
877
|
+
|
878
|
+
def initialize(**args)
|
879
|
+
update!(**args)
|
880
|
+
end
|
881
|
+
|
882
|
+
# Update properties of this object
|
883
|
+
def update!(**args)
|
884
|
+
@description = args[:description] if args.key?(:description)
|
885
|
+
@gke_policy = args[:gke_policy] if args.key?(:gke_policy)
|
886
|
+
@name = args[:name] if args.key?(:name)
|
887
|
+
@update_time = args[:update_time] if args.key?(:update_time)
|
888
|
+
end
|
889
|
+
end
|
890
|
+
|
546
891
|
# A policy for container image binary authorization.
|
547
892
|
class Policy
|
548
893
|
include Google::Apis::Core::Hashable
|
@@ -642,6 +987,34 @@ module Google
|
|
642
987
|
end
|
643
988
|
end
|
644
989
|
|
990
|
+
# A scope specifier for `CheckSet` objects.
|
991
|
+
class Scope
|
992
|
+
include Google::Apis::Core::Hashable
|
993
|
+
|
994
|
+
# Optional. Matches all Kubernetes service accounts in the provided namespace,
|
995
|
+
# unless a more specific `kubernetes_service_account` scope already matched.
|
996
|
+
# Corresponds to the JSON property `kubernetesNamespace`
|
997
|
+
# @return [String]
|
998
|
+
attr_accessor :kubernetes_namespace
|
999
|
+
|
1000
|
+
# Optional. Matches a single Kubernetes service account, e.g. `my-namespace:my-
|
1001
|
+
# service-account`. `kubernetes_service_account` scope is always more specific
|
1002
|
+
# than `kubernetes_namespace` scope for the same namespace.
|
1003
|
+
# Corresponds to the JSON property `kubernetesServiceAccount`
|
1004
|
+
# @return [String]
|
1005
|
+
attr_accessor :kubernetes_service_account
|
1006
|
+
|
1007
|
+
def initialize(**args)
|
1008
|
+
update!(**args)
|
1009
|
+
end
|
1010
|
+
|
1011
|
+
# Update properties of this object
|
1012
|
+
def update!(**args)
|
1013
|
+
@kubernetes_namespace = args[:kubernetes_namespace] if args.key?(:kubernetes_namespace)
|
1014
|
+
@kubernetes_service_account = args[:kubernetes_service_account] if args.key?(:kubernetes_service_account)
|
1015
|
+
end
|
1016
|
+
end
|
1017
|
+
|
645
1018
|
# Request message for `SetIamPolicy` method.
|
646
1019
|
class SetIamPolicyRequest
|
647
1020
|
include Google::Apis::Core::Hashable
|
@@ -657,22 +1030,22 @@ module Google
|
|
657
1030
|
# evaluates to `true`. A condition can add constraints based on attributes of
|
658
1031
|
# the request, the resource, or both. To learn which resources support
|
659
1032
|
# conditions in their IAM policies, see the [IAM documentation](https://cloud.
|
660
|
-
# google.com/iam/help/conditions/resource-policies). **JSON example:** ` "
|
1033
|
+
# google.com/iam/help/conditions/resource-policies). **JSON example:** ``` ` "
|
661
1034
|
# bindings": [ ` "role": "roles/resourcemanager.organizationAdmin", "members": [
|
662
1035
|
# "user:mike@example.com", "group:admins@example.com", "domain:google.com", "
|
663
1036
|
# serviceAccount:my-project-id@appspot.gserviceaccount.com" ] `, ` "role": "
|
664
1037
|
# roles/resourcemanager.organizationViewer", "members": [ "user:eve@example.com"
|
665
1038
|
# ], "condition": ` "title": "expirable access", "description": "Does not grant
|
666
1039
|
# access after Sep 2020", "expression": "request.time < timestamp('2020-10-01T00:
|
667
|
-
# 00:00.000Z')", ` ` ], "etag": "BwWWja0YfJA=", "version": 3 ` **YAML
|
668
|
-
# bindings: - members: - user:mike@example.com - group:admins@
|
669
|
-
# domain:google.com - serviceAccount:my-project-id@appspot.
|
670
|
-
# role: roles/resourcemanager.organizationAdmin - members: -
|
671
|
-
# com role: roles/resourcemanager.organizationViewer condition:
|
672
|
-
# access description: Does not grant access after Sep 2020
|
673
|
-
# time < timestamp('2020-10-01T00:00:00.000Z') etag:
|
674
|
-
# a description of IAM and its features, see the
|
675
|
-
# cloud.google.com/iam/docs/).
|
1040
|
+
# 00:00.000Z')", ` ` ], "etag": "BwWWja0YfJA=", "version": 3 ` ``` **YAML
|
1041
|
+
# example:** ``` bindings: - members: - user:mike@example.com - group:admins@
|
1042
|
+
# example.com - domain:google.com - serviceAccount:my-project-id@appspot.
|
1043
|
+
# gserviceaccount.com role: roles/resourcemanager.organizationAdmin - members: -
|
1044
|
+
# user:eve@example.com role: roles/resourcemanager.organizationViewer condition:
|
1045
|
+
# title: expirable access description: Does not grant access after Sep 2020
|
1046
|
+
# expression: request.time < timestamp('2020-10-01T00:00:00.000Z') etag:
|
1047
|
+
# BwWWja0YfJA= version: 3 ``` For a description of IAM and its features, see the
|
1048
|
+
# [IAM documentation](https://cloud.google.com/iam/docs/).
|
676
1049
|
# Corresponds to the JSON property `policy`
|
677
1050
|
# @return [Google::Apis::BinaryauthorizationV1::IamPolicy]
|
678
1051
|
attr_accessor :policy
|
@@ -742,6 +1115,64 @@ module Google
|
|
742
1115
|
end
|
743
1116
|
end
|
744
1117
|
|
1118
|
+
# Require a signed [DSSE](https://github.com/secure-systems-lab/dsse)
|
1119
|
+
# attestation with type SimpleSigning.
|
1120
|
+
class SimpleSigningAttestationCheck
|
1121
|
+
include Google::Apis::Core::Hashable
|
1122
|
+
|
1123
|
+
# Required. The authenticators required by this check to verify an attestation.
|
1124
|
+
# Typically this is one or more PKIX public keys for signature verification.
|
1125
|
+
# Only one authenticator needs to consider an attestation verified in order for
|
1126
|
+
# an attestation to be considered fully authenticated. In otherwords, this list
|
1127
|
+
# of authenticators is an "OR" of the authenticator results. At least one
|
1128
|
+
# authenticator is required.
|
1129
|
+
# Corresponds to the JSON property `attestationAuthenticators`
|
1130
|
+
# @return [Array<Google::Apis::BinaryauthorizationV1::AttestationAuthenticator>]
|
1131
|
+
attr_accessor :attestation_authenticators
|
1132
|
+
|
1133
|
+
# Optional. The projects where attestations are stored as Container Analysis
|
1134
|
+
# Occurrences. Only one attestation needs to successfully verify an image for
|
1135
|
+
# this check to pass, so a single verified attestation found in any of `
|
1136
|
+
# container_analysis_attestation_projects` is sufficient for the check to pass.
|
1137
|
+
# When fetching Occurrences from Container Analysis, only 'AttestationOccurrence'
|
1138
|
+
# kinds are considered. In the future, additional Occurrence kinds may be added
|
1139
|
+
# to the query.
|
1140
|
+
# Corresponds to the JSON property `containerAnalysisAttestationProjects`
|
1141
|
+
# @return [Array<String>]
|
1142
|
+
attr_accessor :container_analysis_attestation_projects
|
1143
|
+
|
1144
|
+
def initialize(**args)
|
1145
|
+
update!(**args)
|
1146
|
+
end
|
1147
|
+
|
1148
|
+
# Update properties of this object
|
1149
|
+
def update!(**args)
|
1150
|
+
@attestation_authenticators = args[:attestation_authenticators] if args.key?(:attestation_authenticators)
|
1151
|
+
@container_analysis_attestation_projects = args[:container_analysis_attestation_projects] if args.key?(:container_analysis_attestation_projects)
|
1152
|
+
end
|
1153
|
+
end
|
1154
|
+
|
1155
|
+
# A SLSA provenance attestation check, which ensures that images are built by a
|
1156
|
+
# trusted builder using source code from its trusted repositories only.
|
1157
|
+
class SlsaCheck
|
1158
|
+
include Google::Apis::Core::Hashable
|
1159
|
+
|
1160
|
+
# Specifies a list of verification rules for the SLSA attestations. An image is
|
1161
|
+
# considered compliant with the SlsaCheck if any of the rules are satisfied.
|
1162
|
+
# Corresponds to the JSON property `rules`
|
1163
|
+
# @return [Array<Google::Apis::BinaryauthorizationV1::VerificationRule>]
|
1164
|
+
attr_accessor :rules
|
1165
|
+
|
1166
|
+
def initialize(**args)
|
1167
|
+
update!(**args)
|
1168
|
+
end
|
1169
|
+
|
1170
|
+
# Update properties of this object
|
1171
|
+
def update!(**args)
|
1172
|
+
@rules = args[:rules] if args.key?(:rules)
|
1173
|
+
end
|
1174
|
+
end
|
1175
|
+
|
745
1176
|
# Request message for `TestIamPermissions` method.
|
746
1177
|
class TestIamPermissionsRequest
|
747
1178
|
include Google::Apis::Core::Hashable
|
@@ -782,17 +1213,52 @@ module Google
|
|
782
1213
|
end
|
783
1214
|
end
|
784
1215
|
|
1216
|
+
# A trusted directory check, which rejects images that do not come from the set
|
1217
|
+
# of user-configured trusted directories.
|
1218
|
+
class TrustedDirectoryCheck
|
1219
|
+
include Google::Apis::Core::Hashable
|
1220
|
+
|
1221
|
+
# Required. List of trusted directory patterns. A pattern is in the form "
|
1222
|
+
# registry/path/to/directory". The registry domain part is defined as two or
|
1223
|
+
# more dot-separated words, e.g., `us.pkg.dev`, or `gcr.io`. Additionally, `*`
|
1224
|
+
# can be used in three ways as wildcards: 1. leading `*` to match varying
|
1225
|
+
# prefixes in registry subdomain (useful for location prefixes); 2. trailing `*`
|
1226
|
+
# after registry/ to match varying endings; 3. trailing `**` after registry/ to
|
1227
|
+
# match "/" as well. For example: -- `gcr.io/my-project/my-repo` is valid to
|
1228
|
+
# match a single directory -- `*-docker.pkg.dev/my-project/my-repo` or `*.gcr.io/
|
1229
|
+
# my-project` are valid to match varying prefixes -- `gcr.io/my-project/*` will
|
1230
|
+
# match all direct directories in `my-project` -- `gcr.io/my-project/**` would
|
1231
|
+
# match all directories in `my-project` -- `gcr.i*` is not allowed since the
|
1232
|
+
# registry is not completely specified -- `sub*domain.gcr.io/nginx` is not valid
|
1233
|
+
# because only leading `*` or trailing `*` are allowed. -- `*pkg.dev/my-project/
|
1234
|
+
# my-repo` is not valid because leading `*` can only match subdomain -- `**-
|
1235
|
+
# docker.pkg.dev` is not valid because one leading `*` is allowed, and that it
|
1236
|
+
# cannot match `/`
|
1237
|
+
# Corresponds to the JSON property `trustedDirPatterns`
|
1238
|
+
# @return [Array<String>]
|
1239
|
+
attr_accessor :trusted_dir_patterns
|
1240
|
+
|
1241
|
+
def initialize(**args)
|
1242
|
+
update!(**args)
|
1243
|
+
end
|
1244
|
+
|
1245
|
+
# Update properties of this object
|
1246
|
+
def update!(**args)
|
1247
|
+
@trusted_dir_patterns = args[:trusted_dir_patterns] if args.key?(:trusted_dir_patterns)
|
1248
|
+
end
|
1249
|
+
end
|
1250
|
+
|
785
1251
|
# An user owned Grafeas note references a Grafeas Attestation.Authority Note
|
786
1252
|
# created by the user.
|
787
1253
|
class UserOwnedGrafeasNote
|
788
1254
|
include Google::Apis::Core::Hashable
|
789
1255
|
|
790
1256
|
# Output only. This field will contain the service account email address that
|
791
|
-
# this
|
1257
|
+
# this attestor will use as the principal when querying Container Analysis.
|
792
1258
|
# Attestor administrators must grant this service account the IAM role needed to
|
793
1259
|
# read attestations from the note_reference in Container Analysis (`
|
794
1260
|
# containeranalysis.notes.occurrences.viewer`). This email address is fixed for
|
795
|
-
# the lifetime of the
|
1261
|
+
# the lifetime of the attestor, but callers should not make any other
|
796
1262
|
# assumptions about the service account email; future versions may use an email
|
797
1263
|
# based on a different naming pattern.
|
798
1264
|
# Corresponds to the JSON property `delegationServiceAccountEmail`
|
@@ -892,6 +1358,130 @@ module Google
|
|
892
1358
|
@result = args[:result] if args.key?(:result)
|
893
1359
|
end
|
894
1360
|
end
|
1361
|
+
|
1362
|
+
# Specifies verification rules for evaluating the SLSA attestations including:
|
1363
|
+
# which builders to trust, where to fetch the SLSA attestations generated by
|
1364
|
+
# those builders, and other builder-specific evaluation rules such as which
|
1365
|
+
# source repositories are trusted. An image is considered verified by the rule
|
1366
|
+
# if any of the fetched SLSA attestations is verified.
|
1367
|
+
class VerificationRule
|
1368
|
+
include Google::Apis::Core::Hashable
|
1369
|
+
|
1370
|
+
# Specifies the locations for fetching the provenance attestations.
|
1371
|
+
# Corresponds to the JSON property `attestationSource`
|
1372
|
+
# @return [Google::Apis::BinaryauthorizationV1::AttestationSource]
|
1373
|
+
attr_accessor :attestation_source
|
1374
|
+
|
1375
|
+
# If true, require the image to be built from a top-level configuration. `
|
1376
|
+
# trusted_source_repo_patterns` specifies the repositories containing this
|
1377
|
+
# configuration.
|
1378
|
+
# Corresponds to the JSON property `configBasedBuildRequired`
|
1379
|
+
# @return [Boolean]
|
1380
|
+
attr_accessor :config_based_build_required
|
1381
|
+
alias_method :config_based_build_required?, :config_based_build_required
|
1382
|
+
|
1383
|
+
# Each verification rule is used for evaluation against provenances generated by
|
1384
|
+
# a specific builder (group). For some of the builders, such as the Google Cloud
|
1385
|
+
# Build, users don't need to explicitly specify their roots of trust in the
|
1386
|
+
# policy since the evaluation service can automatically fetch them based on the
|
1387
|
+
# builder (group).
|
1388
|
+
# Corresponds to the JSON property `trustedBuilder`
|
1389
|
+
# @return [String]
|
1390
|
+
attr_accessor :trusted_builder
|
1391
|
+
|
1392
|
+
# List of trusted source code repository URL patterns. These patterns match the
|
1393
|
+
# full repository URL without its scheme (e.g. `https://`). The patterns must
|
1394
|
+
# not include schemes. For example, the pattern `source.cloud.google.com/my-
|
1395
|
+
# project/my-repo-name` matches the following URLs: - `source.cloud.google.com/
|
1396
|
+
# my-project/my-repo-name` - `git+ssh://source.cloud.google.com/my-project/my-
|
1397
|
+
# repo-name` - `https://source.cloud.google.com/my-project/my-repo-name` A
|
1398
|
+
# pattern matches a URL either exactly or with `*` wildcards. `*` can be used in
|
1399
|
+
# only two ways: 1. trailing `*` after hosturi/ to match varying endings; 2.
|
1400
|
+
# trailing `**` after hosturi/ to match `/` as well. `*` and `**` can only be
|
1401
|
+
# used as wildcards and can only occur at the end of the pattern after a `/`. (
|
1402
|
+
# So it's not possible to match a URL that contains literal `*`.) For example: -
|
1403
|
+
# `github.com/my-project/my-repo` is valid to match a single repo - `github.com/
|
1404
|
+
# my-project/*` will match all direct repos in `my-project` - `github.com/**`
|
1405
|
+
# matches all repos in GitHub
|
1406
|
+
# Corresponds to the JSON property `trustedSourceRepoPatterns`
|
1407
|
+
# @return [Array<String>]
|
1408
|
+
attr_accessor :trusted_source_repo_patterns
|
1409
|
+
|
1410
|
+
def initialize(**args)
|
1411
|
+
update!(**args)
|
1412
|
+
end
|
1413
|
+
|
1414
|
+
# Update properties of this object
|
1415
|
+
def update!(**args)
|
1416
|
+
@attestation_source = args[:attestation_source] if args.key?(:attestation_source)
|
1417
|
+
@config_based_build_required = args[:config_based_build_required] if args.key?(:config_based_build_required)
|
1418
|
+
@trusted_builder = args[:trusted_builder] if args.key?(:trusted_builder)
|
1419
|
+
@trusted_source_repo_patterns = args[:trusted_source_repo_patterns] if args.key?(:trusted_source_repo_patterns)
|
1420
|
+
end
|
1421
|
+
end
|
1422
|
+
|
1423
|
+
# An image vulnerability check, which rejects images that violate the configured
|
1424
|
+
# vulnerability rules.
|
1425
|
+
class VulnerabilityCheck
|
1426
|
+
include Google::Apis::Core::Hashable
|
1427
|
+
|
1428
|
+
# Optional. A list of specific CVEs to ignore even if the vulnerability level
|
1429
|
+
# violates `maximumUnfixableSeverity` or `maximumFixableSeverity`. CVEs are
|
1430
|
+
# listed in the format of Container Analysis note id. For example: - CVE-2021-
|
1431
|
+
# 20305 - CVE-2020-10543 The CVEs are applicable regardless of note provider
|
1432
|
+
# project, e.g., an entry of `CVE-2021-20305` will allow vulnerabilities with a
|
1433
|
+
# note name of either `projects/goog-vulnz/notes/CVE-2021-20305` or `projects/
|
1434
|
+
# CUSTOM-PROJECT/notes/CVE-2021-20305`.
|
1435
|
+
# Corresponds to the JSON property `allowedCves`
|
1436
|
+
# @return [Array<String>]
|
1437
|
+
attr_accessor :allowed_cves
|
1438
|
+
|
1439
|
+
# Optional. A list of specific CVEs to always raise warnings about even if the
|
1440
|
+
# vulnerability level meets `maximumUnfixableSeverity` or `
|
1441
|
+
# maximumFixableSeverity`. CVEs are listed in the format of Container Analysis
|
1442
|
+
# note id. For example: - CVE-2021-20305 - CVE-2020-10543 The CVEs are
|
1443
|
+
# applicable regardless of note provider project, e.g., an entry of `CVE-2021-
|
1444
|
+
# 20305` will block vulnerabilities with a note name of either `projects/goog-
|
1445
|
+
# vulnz/notes/CVE-2021-20305` or `projects/CUSTOM-PROJECT/notes/CVE-2021-20305`.
|
1446
|
+
# Corresponds to the JSON property `blockedCves`
|
1447
|
+
# @return [Array<String>]
|
1448
|
+
attr_accessor :blocked_cves
|
1449
|
+
|
1450
|
+
# Optional. The projects where vulnerabilities are stored as Container Analysis
|
1451
|
+
# Occurrences. Each project is expressed in the resource format of `projects/[
|
1452
|
+
# PROJECT_ID]`, e.g., `projects/my-gcp-project`. An attempt will be made for
|
1453
|
+
# each project to fetch vulnerabilities, and all valid vulnerabilities will be
|
1454
|
+
# used to check against the vulnerability policy. If no valid scan is found in
|
1455
|
+
# all projects configured here, an error will be returned for the check.
|
1456
|
+
# Corresponds to the JSON property `containerAnalysisVulnerabilityProjects`
|
1457
|
+
# @return [Array<String>]
|
1458
|
+
attr_accessor :container_analysis_vulnerability_projects
|
1459
|
+
|
1460
|
+
# Required. The threshold for severity for which a fix is currently available.
|
1461
|
+
# This field is required and must be set.
|
1462
|
+
# Corresponds to the JSON property `maximumFixableSeverity`
|
1463
|
+
# @return [String]
|
1464
|
+
attr_accessor :maximum_fixable_severity
|
1465
|
+
|
1466
|
+
# Required. The threshold for severity for which a fix isn't currently available.
|
1467
|
+
# This field is required and must be set.
|
1468
|
+
# Corresponds to the JSON property `maximumUnfixableSeverity`
|
1469
|
+
# @return [String]
|
1470
|
+
attr_accessor :maximum_unfixable_severity
|
1471
|
+
|
1472
|
+
def initialize(**args)
|
1473
|
+
update!(**args)
|
1474
|
+
end
|
1475
|
+
|
1476
|
+
# Update properties of this object
|
1477
|
+
def update!(**args)
|
1478
|
+
@allowed_cves = args[:allowed_cves] if args.key?(:allowed_cves)
|
1479
|
+
@blocked_cves = args[:blocked_cves] if args.key?(:blocked_cves)
|
1480
|
+
@container_analysis_vulnerability_projects = args[:container_analysis_vulnerability_projects] if args.key?(:container_analysis_vulnerability_projects)
|
1481
|
+
@maximum_fixable_severity = args[:maximum_fixable_severity] if args.key?(:maximum_fixable_severity)
|
1482
|
+
@maximum_unfixable_severity = args[:maximum_unfixable_severity] if args.key?(:maximum_unfixable_severity)
|
1483
|
+
end
|
1484
|
+
end
|
895
1485
|
end
|
896
1486
|
end
|
897
1487
|
end
|