diff --git a/cloud/aws/deploy/bucket.go b/cloud/aws/deploy/bucket.go index 1bfa65a28..b7a6df81f 100644 --- a/cloud/aws/deploy/bucket.go +++ b/cloud/aws/deploy/bucket.go @@ -201,6 +201,30 @@ func (a *NitricAwsPulumiProvider) Bucket(ctx *pulumi.Context, parent pulumi.Reso a.Buckets[name] = bucket + if len(config.CorsRules) > 0 { + corsRules := s3.BucketCorsConfigurationV2CorsRuleArray{} + for _, rule := range config.CorsRules { + corsRule := s3.BucketCorsConfigurationV2CorsRuleArgs{ + AllowedOrigins: pulumi.ToStringArray(rule.AllowedOrigins), + AllowedMethods: pulumi.ToStringArray(rule.AllowedMethods), + AllowedHeaders: pulumi.ToStringArray(rule.AllowedHeaders), + ExposeHeaders: pulumi.ToStringArray(rule.ExposeHeaders), + } + if rule.MaxAgeSeconds > 0 { + corsRule.MaxAgeSeconds = pulumi.IntPtr(int(rule.MaxAgeSeconds)) + } + corsRules = append(corsRules, corsRule) + } + + _, err := s3.NewBucketCorsConfigurationV2(ctx, fmt.Sprintf("%s-cors", name), &s3.BucketCorsConfigurationV2Args{ + Bucket: bucket.ID().ToStringOutput(), + CorsRules: corsRules, + }, opts...) + if err != nil { + return fmt.Errorf("unable to create CORS configuration for bucket %s: %w", name, err) + } + } + if len(config.Listeners) > 0 { notificationName := fmt.Sprintf("notification-%s", name) notification, err := createNotification(ctx, notificationName, &S3NotificationArgs{ diff --git a/cloud/aws/deploy/bucket_test.go b/cloud/aws/deploy/bucket_test.go new file mode 100644 index 000000000..7952975a2 --- /dev/null +++ b/cloud/aws/deploy/bucket_test.go @@ -0,0 +1,205 @@ +// Copyright Nitric Pty Ltd. +// +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +package deploy + +import ( + "sync" + "testing" + + "github.com/nitrictech/nitric/cloud/aws/common" + "github.com/pulumi/pulumi-aws/sdk/v5/go/aws/s3" + "github.com/pulumi/pulumi/sdk/v3/go/common/resource" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + + deploymentspb "github.com/nitrictech/nitric/core/pkg/proto/deployments/v1" +) + +type bucketMocks struct { + mu sync.Mutex + resources []mockResource +} + +type mockResource struct { + TypeToken string + Name string + Inputs resource.PropertyMap +} + +func (m *bucketMocks) NewResource(args pulumi.MockResourceArgs) (string, resource.PropertyMap, error) { + m.mu.Lock() + defer m.mu.Unlock() + + m.resources = append(m.resources, mockResource{ + TypeToken: args.TypeToken, + Name: args.Name, + Inputs: args.Inputs, + }) + + // Return a fake ID and the inputs as outputs + return args.Name + "-id", args.Inputs, nil +} + +func (m *bucketMocks) Call(args pulumi.MockCallArgs) (resource.PropertyMap, error) { + return resource.PropertyMap{}, nil +} + +func (m *bucketMocks) findResources(typeToken string) []mockResource { + m.mu.Lock() + defer m.mu.Unlock() + + var found []mockResource + for _, r := range m.resources { + if r.TypeToken == typeToken { + found = append(found, r) + } + } + return found +} + +func TestBucket_WithCorsRules_CreatesS3CorsConfiguration(t *testing.T) { + mocks := &bucketMocks{} + + err := pulumi.RunErr(func(ctx *pulumi.Context) error { + provider := &NitricAwsPulumiProvider{ + StackId: "test-stack", + AwsConfig: &common.AwsConfig{}, + Buckets: map[string]*s3.Bucket{}, + BucketNotifications: map[string]*s3.BucketNotification{}, + } + + return provider.Bucket(ctx, nil, "test-bucket", &deploymentspb.Bucket{ + CorsRules: []*deploymentspb.BucketCorsRule{ + { + AllowedOrigins: []string{"https://example.com"}, + AllowedMethods: []string{"GET", "POST"}, + AllowedHeaders: []string{"Content-Type", "Authorization"}, + ExposeHeaders: []string{"ETag"}, + MaxAgeSeconds: 3600, + }, + }, + }) + }, pulumi.WithMocks("test", "test", mocks)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // Verify an S3 bucket was created + buckets := mocks.findResources("aws:s3/bucket:Bucket") + if len(buckets) != 1 { + t.Fatalf("expected 1 S3 bucket, got %d", len(buckets)) + } + + // Verify a CORS configuration was created + corsConfigs := mocks.findResources("aws:s3/bucketCorsConfigurationV2:BucketCorsConfigurationV2") + if len(corsConfigs) != 1 { + t.Fatalf("expected 1 CORS configuration, got %d", len(corsConfigs)) + } + + // Verify the CORS rule field values + corsRules, ok := corsConfigs[0].Inputs["corsRules"] + if !ok { + t.Fatal("expected CORS configuration to have 'corsRules' input") + } + rules := corsRules.ArrayValue() + if len(rules) != 1 { + t.Fatalf("expected 1 CORS rule, got %d", len(rules)) + } + rule := rules[0].ObjectValue() + + origins := rule["allowedOrigins"].ArrayValue() + if len(origins) != 1 || origins[0].StringValue() != "https://example.com" { + t.Fatalf("unexpected allowedOrigins: %v", origins) + } + methods := rule["allowedMethods"].ArrayValue() + if len(methods) != 2 || methods[0].StringValue() != "GET" { + t.Fatalf("unexpected allowedMethods: %v", methods) + } + headers := rule["allowedHeaders"].ArrayValue() + if len(headers) != 2 || headers[0].StringValue() != "Content-Type" { + t.Fatalf("unexpected allowedHeaders: %v", headers) + } + expose := rule["exposeHeaders"].ArrayValue() + if len(expose) != 1 || expose[0].StringValue() != "ETag" { + t.Fatalf("unexpected exposeHeaders: %v", expose) + } + maxAge, ok := rule["maxAgeSeconds"] + if !ok || maxAge.NumberValue() != 3600 { + t.Fatalf("unexpected maxAgeSeconds: %v", maxAge) + } +} + +func TestBucket_WithoutCorsRules_NoCorsConfiguration(t *testing.T) { + mocks := &bucketMocks{} + + err := pulumi.RunErr(func(ctx *pulumi.Context) error { + provider := &NitricAwsPulumiProvider{ + StackId: "test-stack", + AwsConfig: &common.AwsConfig{}, + Buckets: map[string]*s3.Bucket{}, + BucketNotifications: map[string]*s3.BucketNotification{}, + } + + return provider.Bucket(ctx, nil, "test-bucket", &deploymentspb.Bucket{}) + }, pulumi.WithMocks("test", "test", mocks)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // Verify no CORS configuration was created + corsConfigs := mocks.findResources("aws:s3/bucketCorsConfigurationV2:BucketCorsConfigurationV2") + if len(corsConfigs) != 0 { + t.Fatalf("expected 0 CORS configurations, got %d", len(corsConfigs)) + } +} + +func TestBucket_MultipleCorsRules(t *testing.T) { + mocks := &bucketMocks{} + + err := pulumi.RunErr(func(ctx *pulumi.Context) error { + provider := &NitricAwsPulumiProvider{ + StackId: "test-stack", + AwsConfig: &common.AwsConfig{}, + Buckets: map[string]*s3.Bucket{}, + BucketNotifications: map[string]*s3.BucketNotification{}, + } + + return provider.Bucket(ctx, nil, "test-bucket", &deploymentspb.Bucket{ + CorsRules: []*deploymentspb.BucketCorsRule{ + { + AllowedOrigins: []string{"https://example.com"}, + AllowedMethods: []string{"GET"}, + MaxAgeSeconds: 300, + }, + { + AllowedOrigins: []string{"https://other.com"}, + AllowedMethods: []string{"PUT", "POST"}, + AllowedHeaders: []string{"*"}, + MaxAgeSeconds: 600, + }, + }, + }) + }, pulumi.WithMocks("test", "test", mocks)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // Verify exactly one CORS configuration resource (containing both rules) + corsConfigs := mocks.findResources("aws:s3/bucketCorsConfigurationV2:BucketCorsConfigurationV2") + if len(corsConfigs) != 1 { + t.Fatalf("expected 1 CORS configuration, got %d", len(corsConfigs)) + } +} diff --git a/cloud/aws/deploytf/.nitric/modules/bucket/main.tf b/cloud/aws/deploytf/.nitric/modules/bucket/main.tf index 4c6f41280..2da81a41b 100644 --- a/cloud/aws/deploytf/.nitric/modules/bucket/main.tf +++ b/cloud/aws/deploytf/.nitric/modules/bucket/main.tf @@ -19,6 +19,23 @@ resource "aws_s3_bucket" "bucket" { } } +# CORS configuration for the bucket +resource "aws_s3_bucket_cors_configuration" "cors" { + count = length(var.cors_rules) > 0 ? 1 : 0 + bucket = aws_s3_bucket.bucket.id + + dynamic "cors_rule" { + for_each = var.cors_rules + content { + allowed_origins = cors_rule.value.allowed_origins + allowed_methods = cors_rule.value.allowed_methods + allowed_headers = cors_rule.value.allowed_headers + expose_headers = cors_rule.value.expose_headers + max_age_seconds = cors_rule.value.max_age_seconds + } + } +} + # Deploy bucket lambda invocation permissions resource "aws_lambda_permission" "allow_bucket" { for_each = var.notification_targets diff --git a/cloud/aws/deploytf/.nitric/modules/bucket/variables.tf b/cloud/aws/deploytf/.nitric/modules/bucket/variables.tf index 8e59649bc..deefc013f 100644 --- a/cloud/aws/deploytf/.nitric/modules/bucket/variables.tf +++ b/cloud/aws/deploytf/.nitric/modules/bucket/variables.tf @@ -16,3 +16,15 @@ variable "notification_targets" { events = list(string) })) } + +variable "cors_rules" { + description = "CORS rules for the bucket" + type = list(object({ + allowed_origins = list(string) + allowed_methods = list(string) + allowed_headers = list(string) + expose_headers = list(string) + max_age_seconds = number + })) + default = [] +} diff --git a/cloud/aws/deploytf/bucket.go b/cloud/aws/deploytf/bucket.go index 34970aca8..a5e982f3d 100644 --- a/cloud/aws/deploytf/bucket.go +++ b/cloud/aws/deploytf/bucket.go @@ -49,10 +49,22 @@ func (n *NitricAwsTerraformProvider) Bucket(stack cdktf.TerraformStack, name str } } + var corsRules []map[string]interface{} + for _, rule := range config.CorsRules { + corsRules = append(corsRules, map[string]interface{}{ + "allowed_origins": jsii.Strings(rule.AllowedOrigins...), + "allowed_methods": jsii.Strings(rule.AllowedMethods...), + "allowed_headers": jsii.Strings(rule.AllowedHeaders...), + "expose_headers": jsii.Strings(rule.ExposeHeaders...), + "max_age_seconds": jsii.Number(float64(rule.MaxAgeSeconds)), + }) + } + n.Buckets[name] = bucket.NewBucket(stack, jsii.Sprintf("bucket_%s", name), &bucket.BucketConfig{ BucketName: &name, StackId: n.Stack.StackIdOutput(), NotificationTargets: ¬ificationTargets, + CorsRules: &corsRules, }) return nil diff --git a/cloud/aws/deploytf/generated/api/jsii/api-0.0.0.tgz b/cloud/aws/deploytf/generated/api/jsii/api-0.0.0.tgz index 1eae73f39..d2c4b97a8 100644 Binary files a/cloud/aws/deploytf/generated/api/jsii/api-0.0.0.tgz and b/cloud/aws/deploytf/generated/api/jsii/api-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/bucket/Bucket.go b/cloud/aws/deploytf/generated/bucket/Bucket.go index 3fde741fc..e43843a9e 100644 --- a/cloud/aws/deploytf/generated/bucket/Bucket.go +++ b/cloud/aws/deploytf/generated/bucket/Bucket.go @@ -21,6 +21,8 @@ type Bucket interface { CdktfStack() cdktf.TerraformStack // Experimental. ConstructNodeMetadata() *map[string]interface{} + CorsRules() interface{} + SetCorsRules(val interface{}) // Experimental. DependsOn() *[]*string // Experimental. @@ -120,6 +122,16 @@ func (j *jsiiProxy_Bucket) ConstructNodeMetadata() *map[string]interface{} { return returns } +func (j *jsiiProxy_Bucket) CorsRules() interface{} { + var returns interface{} + _jsii_.Get( + j, + "corsRules", + &returns, + ) + return returns +} + func (j *jsiiProxy_Bucket) DependsOn() *[]*string { var returns *[]*string _jsii_.Get( @@ -279,6 +291,17 @@ func (j *jsiiProxy_Bucket)SetBucketName(val *string) { ) } +func (j *jsiiProxy_Bucket)SetCorsRules(val interface{}) { + if err := j.validateSetCorsRulesParameters(val); err != nil { + panic(err) + } + _jsii_.Set( + j, + "corsRules", + val, + ) +} + func (j *jsiiProxy_Bucket)SetDependsOn(val *[]*string) { _jsii_.Set( j, diff --git a/cloud/aws/deploytf/generated/bucket/BucketConfig.go b/cloud/aws/deploytf/generated/bucket/BucketConfig.go index 8761406ae..1da2053dc 100644 --- a/cloud/aws/deploytf/generated/bucket/BucketConfig.go +++ b/cloud/aws/deploytf/generated/bucket/BucketConfig.go @@ -21,5 +21,7 @@ type BucketConfig struct { NotificationTargets interface{} `field:"required" json:"notificationTargets" yaml:"notificationTargets"` // The ID of the Nitric stack. StackId *string `field:"required" json:"stackId" yaml:"stackId"` + // CORS rules for the bucket. + CorsRules interface{} `field:"optional" json:"corsRules" yaml:"corsRules"` } diff --git a/cloud/aws/deploytf/generated/bucket/Bucket__checks.go b/cloud/aws/deploytf/generated/bucket/Bucket__checks.go index b1fd8a491..c4a8a96b1 100644 --- a/cloud/aws/deploytf/generated/bucket/Bucket__checks.go +++ b/cloud/aws/deploytf/generated/bucket/Bucket__checks.go @@ -98,6 +98,14 @@ func (j *jsiiProxy_Bucket) validateSetBucketNameParameters(val *string) error { return nil } +func (j *jsiiProxy_Bucket) validateSetCorsRulesParameters(val interface{}) error { + if val == nil { + return fmt.Errorf("parameter val is required, but nil was provided") + } + + return nil +} + func (j *jsiiProxy_Bucket) validateSetNotificationTargetsParameters(val interface{}) error { if val == nil { return fmt.Errorf("parameter val is required, but nil was provided") diff --git a/cloud/aws/deploytf/generated/bucket/Bucket__no_checks.go b/cloud/aws/deploytf/generated/bucket/Bucket__no_checks.go index f13b5347c..c4b42ed83 100644 --- a/cloud/aws/deploytf/generated/bucket/Bucket__no_checks.go +++ b/cloud/aws/deploytf/generated/bucket/Bucket__no_checks.go @@ -36,6 +36,10 @@ func (j *jsiiProxy_Bucket) validateSetBucketNameParameters(val *string) error { return nil } +func (j *jsiiProxy_Bucket) validateSetCorsRulesParameters(val interface{}) error { + return nil +} + func (j *jsiiProxy_Bucket) validateSetNotificationTargetsParameters(val interface{}) error { return nil } diff --git a/cloud/aws/deploytf/generated/bucket/jsii/bucket-0.0.0.tgz b/cloud/aws/deploytf/generated/bucket/jsii/bucket-0.0.0.tgz index e4467fc7a..72f91d488 100644 Binary files a/cloud/aws/deploytf/generated/bucket/jsii/bucket-0.0.0.tgz and b/cloud/aws/deploytf/generated/bucket/jsii/bucket-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/bucket/main.go b/cloud/aws/deploytf/generated/bucket/main.go index d0bb22b35..f493d3b1e 100644 --- a/cloud/aws/deploytf/generated/bucket/main.go +++ b/cloud/aws/deploytf/generated/bucket/main.go @@ -18,6 +18,7 @@ func init() { _jsii_.MemberProperty{JsiiProperty: "bucketName", GoGetter: "BucketName"}, _jsii_.MemberProperty{JsiiProperty: "cdktfStack", GoGetter: "CdktfStack"}, _jsii_.MemberProperty{JsiiProperty: "constructNodeMetadata", GoGetter: "ConstructNodeMetadata"}, + _jsii_.MemberProperty{JsiiProperty: "corsRules", GoGetter: "CorsRules"}, _jsii_.MemberProperty{JsiiProperty: "dependsOn", GoGetter: "DependsOn"}, _jsii_.MemberProperty{JsiiProperty: "forEach", GoGetter: "ForEach"}, _jsii_.MemberProperty{JsiiProperty: "fqn", GoGetter: "Fqn"}, diff --git a/cloud/aws/deploytf/generated/cdn/jsii/cdn-0.0.0.tgz b/cloud/aws/deploytf/generated/cdn/jsii/cdn-0.0.0.tgz index 359ae8d87..4b0aa88fe 100644 Binary files a/cloud/aws/deploytf/generated/cdn/jsii/cdn-0.0.0.tgz and b/cloud/aws/deploytf/generated/cdn/jsii/cdn-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/http_proxy/jsii/http_proxy-0.0.0.tgz b/cloud/aws/deploytf/generated/http_proxy/jsii/http_proxy-0.0.0.tgz index 9734e61c9..cd53128c0 100644 Binary files a/cloud/aws/deploytf/generated/http_proxy/jsii/http_proxy-0.0.0.tgz and b/cloud/aws/deploytf/generated/http_proxy/jsii/http_proxy-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/keyvalue/jsii/keyvalue-0.0.0.tgz b/cloud/aws/deploytf/generated/keyvalue/jsii/keyvalue-0.0.0.tgz index 584ac664c..3c127c615 100644 Binary files a/cloud/aws/deploytf/generated/keyvalue/jsii/keyvalue-0.0.0.tgz and b/cloud/aws/deploytf/generated/keyvalue/jsii/keyvalue-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/parameter/jsii/parameter-0.0.0.tgz b/cloud/aws/deploytf/generated/parameter/jsii/parameter-0.0.0.tgz index 9fd46fcf0..f73c88c12 100644 Binary files a/cloud/aws/deploytf/generated/parameter/jsii/parameter-0.0.0.tgz and b/cloud/aws/deploytf/generated/parameter/jsii/parameter-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/policy/jsii/policy-0.0.0.tgz b/cloud/aws/deploytf/generated/policy/jsii/policy-0.0.0.tgz index 949457302..93da83168 100644 Binary files a/cloud/aws/deploytf/generated/policy/jsii/policy-0.0.0.tgz and b/cloud/aws/deploytf/generated/policy/jsii/policy-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/queue/jsii/queue-0.0.0.tgz b/cloud/aws/deploytf/generated/queue/jsii/queue-0.0.0.tgz index 01de20692..0759a2d6c 100644 Binary files a/cloud/aws/deploytf/generated/queue/jsii/queue-0.0.0.tgz and b/cloud/aws/deploytf/generated/queue/jsii/queue-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/rds/jsii/rds-0.0.0.tgz b/cloud/aws/deploytf/generated/rds/jsii/rds-0.0.0.tgz index 9e4e67e97..661dbe0d6 100644 Binary files a/cloud/aws/deploytf/generated/rds/jsii/rds-0.0.0.tgz and b/cloud/aws/deploytf/generated/rds/jsii/rds-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/schedule/jsii/schedule-0.0.0.tgz b/cloud/aws/deploytf/generated/schedule/jsii/schedule-0.0.0.tgz index b389bf7e7..5e8c0fef5 100644 Binary files a/cloud/aws/deploytf/generated/schedule/jsii/schedule-0.0.0.tgz and b/cloud/aws/deploytf/generated/schedule/jsii/schedule-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/secret/jsii/secret-0.0.0.tgz b/cloud/aws/deploytf/generated/secret/jsii/secret-0.0.0.tgz index 0d26694d0..7dbd8731e 100644 Binary files a/cloud/aws/deploytf/generated/secret/jsii/secret-0.0.0.tgz and b/cloud/aws/deploytf/generated/secret/jsii/secret-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/service/jsii/service-0.0.0.tgz b/cloud/aws/deploytf/generated/service/jsii/service-0.0.0.tgz index c6d905ada..ba6d3bbb6 100644 Binary files a/cloud/aws/deploytf/generated/service/jsii/service-0.0.0.tgz and b/cloud/aws/deploytf/generated/service/jsii/service-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/sql/jsii/sql-0.0.0.tgz b/cloud/aws/deploytf/generated/sql/jsii/sql-0.0.0.tgz index 589001a11..c497c4ebe 100644 Binary files a/cloud/aws/deploytf/generated/sql/jsii/sql-0.0.0.tgz and b/cloud/aws/deploytf/generated/sql/jsii/sql-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/stack/jsii/stack-0.0.0.tgz b/cloud/aws/deploytf/generated/stack/jsii/stack-0.0.0.tgz index c0d0b3327..d0d43a375 100644 Binary files a/cloud/aws/deploytf/generated/stack/jsii/stack-0.0.0.tgz and b/cloud/aws/deploytf/generated/stack/jsii/stack-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/topic/jsii/topic-0.0.0.tgz b/cloud/aws/deploytf/generated/topic/jsii/topic-0.0.0.tgz index 61f72fa14..fab007754 100644 Binary files a/cloud/aws/deploytf/generated/topic/jsii/topic-0.0.0.tgz and b/cloud/aws/deploytf/generated/topic/jsii/topic-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/vpc/jsii/vpc-0.0.0.tgz b/cloud/aws/deploytf/generated/vpc/jsii/vpc-0.0.0.tgz index 8b97f4560..d8202f330 100644 Binary files a/cloud/aws/deploytf/generated/vpc/jsii/vpc-0.0.0.tgz and b/cloud/aws/deploytf/generated/vpc/jsii/vpc-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/website/jsii/website-0.0.0.tgz b/cloud/aws/deploytf/generated/website/jsii/website-0.0.0.tgz index 5d0e3f748..8e1504b0a 100644 Binary files a/cloud/aws/deploytf/generated/website/jsii/website-0.0.0.tgz and b/cloud/aws/deploytf/generated/website/jsii/website-0.0.0.tgz differ diff --git a/cloud/aws/deploytf/generated/websocket/jsii/websocket-0.0.0.tgz b/cloud/aws/deploytf/generated/websocket/jsii/websocket-0.0.0.tgz index b9f232ec4..e834c1ced 100644 Binary files a/cloud/aws/deploytf/generated/websocket/jsii/websocket-0.0.0.tgz and b/cloud/aws/deploytf/generated/websocket/jsii/websocket-0.0.0.tgz differ diff --git a/cloud/azure/deploy/bucket.go b/cloud/azure/deploy/bucket.go index 1cfbb434a..039913668 100644 --- a/cloud/azure/deploy/bucket.go +++ b/cloud/azure/deploy/bucket.go @@ -88,6 +88,11 @@ func (p *NitricAzurePulumiProvider) Bucket(ctx *pulumi.Context, parent pulumi.Re var err error opts := []pulumi.ResourceOption{pulumi.Parent(parent)} + if len(config.CorsRules) > 0 { + return fmt.Errorf("bucket %q has CORS rules configured, but Azure does not support per-container CORS. "+ + "CORS must be configured at the Storage Account level", name) + } + p.Buckets[name], err = storage.NewBlobContainer(ctx, ResourceName(ctx, name, StorageContainerRT), &storage.BlobContainerArgs{ ResourceGroupName: p.ResourceGroup.Name, AccountName: p.StorageAccount.Name, diff --git a/cloud/azure/deploytf/bucket.go b/cloud/azure/deploytf/bucket.go index f19df6755..5b05843eb 100644 --- a/cloud/azure/deploytf/bucket.go +++ b/cloud/azure/deploytf/bucket.go @@ -15,6 +15,8 @@ package deploytf import ( + "fmt" + "github.com/aws/jsii-runtime-go" "github.com/hashicorp/terraform-cdk-go/cdktf" "github.com/nitrictech/nitric/cloud/azure/deploytf/generated/bucket" @@ -45,6 +47,11 @@ func eventTypeToStorageEventType(eventType storagepb.BlobEventType) []*string { // Bucket - Deploy a Storage Bucket func (n *NitricAzureTerraformProvider) Bucket(stack cdktf.TerraformStack, name string, config *deploymentspb.Bucket) error { + if len(config.CorsRules) > 0 { + return fmt.Errorf("bucket %q has CORS rules configured, but Azure does not support per-container CORS. "+ + "CORS must be configured at the Storage Account level", name) + } + listeners := map[string]BucketSubscriber{} allDependants := []cdktf.ITerraformDependable{} diff --git a/cloud/gcp/deploy/bucket.go b/cloud/gcp/deploy/bucket.go index a0f68cc81..0d0ecc3e9 100644 --- a/cloud/gcp/deploy/bucket.go +++ b/cloud/gcp/deploy/bucket.go @@ -35,10 +35,37 @@ func (p *NitricGcpPulumiProvider) Bucket(ctx *pulumi.Context, parent pulumi.Reso resourceLabels := common.Tags(p.StackId, name, resources.Bucket) - p.Buckets[name], err = storage.NewBucket(ctx, name, &storage.BucketArgs{ + bucketArgs := &storage.BucketArgs{ Location: pulumi.String(p.Region), Labels: pulumi.ToStringMap(resourceLabels), - }, p.WithDefaultResourceOptions(opts...)...) + } + + if len(config.CorsRules) > 0 { + corsRules := storage.BucketCorArray{} + warnedAllowedHeaders := false + for _, rule := range config.CorsRules { + if len(rule.AllowedHeaders) > 0 && !warnedAllowedHeaders { + ctx.Log.Warn(fmt.Sprintf("bucket %q: GCP Cloud Storage does not support AllowedHeaders in CORS configuration. "+ + "GCS automatically allows all request headers when the origin and method match. "+ + "The AllowedHeaders setting will be ignored.", name), nil) + warnedAllowedHeaders = true + } + + corsRule := storage.BucketCorArgs{ + Origins: pulumi.ToStringArray(rule.AllowedOrigins), + Methods: pulumi.ToStringArray(rule.AllowedMethods), + // GCP's ResponseHeaders maps to the CORS Access-Control-Expose-Headers header + ResponseHeaders: pulumi.ToStringArray(rule.ExposeHeaders), + } + if rule.MaxAgeSeconds > 0 { + corsRule.MaxAgeSeconds = pulumi.IntPtr(int(rule.MaxAgeSeconds)) + } + corsRules = append(corsRules, corsRule) + } + bucketArgs.Cors = corsRules + } + + p.Buckets[name], err = storage.NewBucket(ctx, name, bucketArgs, p.WithDefaultResourceOptions(opts...)...) if err != nil { return err } diff --git a/cloud/gcp/deploy/bucket_test.go b/cloud/gcp/deploy/bucket_test.go new file mode 100644 index 000000000..5d4d15d46 --- /dev/null +++ b/cloud/gcp/deploy/bucket_test.go @@ -0,0 +1,221 @@ +// Copyright Nitric Pty Ltd. +// +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +package deploy + +import ( + "sync" + "testing" + + "github.com/nitrictech/nitric/cloud/common/deploy" + "github.com/pulumi/pulumi-gcp/sdk/v8/go/gcp/storage" + "github.com/pulumi/pulumi/sdk/v3/go/common/resource" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + + deploymentspb "github.com/nitrictech/nitric/core/pkg/proto/deployments/v1" +) + +type bucketMocks struct { + mu sync.Mutex + resources []mockResource +} + +type mockResource struct { + TypeToken string + Name string + Inputs resource.PropertyMap +} + +func (m *bucketMocks) NewResource(args pulumi.MockResourceArgs) (string, resource.PropertyMap, error) { + m.mu.Lock() + defer m.mu.Unlock() + + m.resources = append(m.resources, mockResource{ + TypeToken: args.TypeToken, + Name: args.Name, + Inputs: args.Inputs, + }) + + return args.Name + "-id", args.Inputs, nil +} + +func (m *bucketMocks) Call(args pulumi.MockCallArgs) (resource.PropertyMap, error) { + return resource.PropertyMap{}, nil +} + +func (m *bucketMocks) findResources(typeToken string) []mockResource { + m.mu.Lock() + defer m.mu.Unlock() + + var found []mockResource + for _, r := range m.resources { + if r.TypeToken == typeToken { + found = append(found, r) + } + } + return found +} + +func newTestGcpProvider(ctx *pulumi.Context) (*NitricGcpPulumiProvider, error) { + project := &Project{Name: "test-project"} + err := ctx.RegisterComponentResource("ntiricgcp:project:GcpProject", "test-project", project) + if err != nil { + return nil, err + } + + return &NitricGcpPulumiProvider{ + CommonStackDetails: &deploy.CommonStackDetails{Region: "us-central1"}, + Buckets: map[string]*storage.Bucket{}, + StackId: "test-stack", + Project: project, + }, nil +} + +func TestBucket_WithCorsRules_SetsCorsOnBucket(t *testing.T) { + mocks := &bucketMocks{} + + err := pulumi.RunErr(func(ctx *pulumi.Context) error { + provider, err := newTestGcpProvider(ctx) + if err != nil { + return err + } + + return provider.Bucket(ctx, nil, "test-bucket", &deploymentspb.Bucket{ + CorsRules: []*deploymentspb.BucketCorsRule{ + { + AllowedOrigins: []string{"https://example.com"}, + AllowedMethods: []string{"GET", "POST"}, + AllowedHeaders: []string{"Content-Type"}, + ExposeHeaders: []string{"ETag"}, + MaxAgeSeconds: 3600, + }, + }, + }) + }, pulumi.WithMocks("test", "test", mocks)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // GCP sets CORS on the bucket itself (not a separate resource) + buckets := mocks.findResources("gcp:storage/bucket:Bucket") + if len(buckets) != 1 { + t.Fatalf("expected 1 GCS bucket, got %d", len(buckets)) + } + + // Verify the bucket has cors property set + bucket := buckets[0] + cors, ok := bucket.Inputs["cors"] + if !ok { + t.Fatal("expected bucket to have 'cors' property set") + } + + corsArr := cors.ArrayValue() + if len(corsArr) != 1 { + t.Fatalf("expected 1 CORS rule, got %d", len(corsArr)) + } + + // Verify field values + rule := corsArr[0].ObjectValue() + + origins := rule["origins"].ArrayValue() + if len(origins) != 1 || origins[0].StringValue() != "https://example.com" { + t.Fatalf("unexpected origins: %v", origins) + } + methods := rule["methods"].ArrayValue() + if len(methods) != 2 || methods[0].StringValue() != "GET" { + t.Fatalf("unexpected methods: %v", methods) + } + // GCP maps ExposeHeaders to ResponseHeaders + responseHeaders := rule["responseHeaders"].ArrayValue() + if len(responseHeaders) != 1 || responseHeaders[0].StringValue() != "ETag" { + t.Fatalf("unexpected responseHeaders: %v", responseHeaders) + } + maxAge, ok := rule["maxAgeSeconds"] + if !ok || maxAge.NumberValue() != 3600 { + t.Fatalf("unexpected maxAgeSeconds: %v", maxAge) + } +} + +func TestBucket_MultipleCorsRules(t *testing.T) { + mocks := &bucketMocks{} + + err := pulumi.RunErr(func(ctx *pulumi.Context) error { + provider, err := newTestGcpProvider(ctx) + if err != nil { + return err + } + + return provider.Bucket(ctx, nil, "test-bucket", &deploymentspb.Bucket{ + CorsRules: []*deploymentspb.BucketCorsRule{ + { + AllowedOrigins: []string{"https://example.com"}, + AllowedMethods: []string{"GET"}, + MaxAgeSeconds: 300, + }, + { + AllowedOrigins: []string{"https://other.com"}, + AllowedMethods: []string{"PUT", "POST"}, + ExposeHeaders: []string{"X-Custom"}, + MaxAgeSeconds: 600, + }, + }, + }) + }, pulumi.WithMocks("test", "test", mocks)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + buckets := mocks.findResources("gcp:storage/bucket:Bucket") + if len(buckets) != 1 { + t.Fatalf("expected 1 GCS bucket, got %d", len(buckets)) + } + + cors, ok := buckets[0].Inputs["cors"] + if !ok { + t.Fatal("expected bucket to have 'cors' property set") + } + if len(cors.ArrayValue()) != 2 { + t.Fatalf("expected 2 CORS rules, got %d", len(cors.ArrayValue())) + } +} + +func TestBucket_WithoutCorsRules_NoCorsOnBucket(t *testing.T) { + mocks := &bucketMocks{} + + err := pulumi.RunErr(func(ctx *pulumi.Context) error { + provider, err := newTestGcpProvider(ctx) + if err != nil { + return err + } + + return provider.Bucket(ctx, nil, "test-bucket", &deploymentspb.Bucket{}) + }, pulumi.WithMocks("test", "test", mocks)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + buckets := mocks.findResources("gcp:storage/bucket:Bucket") + if len(buckets) != 1 { + t.Fatalf("expected 1 GCS bucket, got %d", len(buckets)) + } + + // Verify no cors property + bucket := buckets[0] + cors, ok := bucket.Inputs["cors"] + if ok && len(cors.ArrayValue()) > 0 { + t.Fatal("expected bucket to NOT have 'cors' property set") + } +} diff --git a/cloud/gcp/deploytf/.nitric/modules/bucket/main.tf b/cloud/gcp/deploytf/.nitric/modules/bucket/main.tf index eaa2c7dd9..9b389911b 100644 --- a/cloud/gcp/deploytf/.nitric/modules/bucket/main.tf +++ b/cloud/gcp/deploytf/.nitric/modules/bucket/main.tf @@ -12,7 +12,7 @@ resource "random_id" "bucket_id" { data "google_client_config" "this" { } -# Google Stora bucket +# Google Storage bucket resource "google_storage_bucket" "bucket" { name = "${var.bucket_name}-${random_id.bucket_id.hex}" location = data.google_client_config.this.region @@ -21,6 +21,16 @@ resource "google_storage_bucket" "bucket" { "x-nitric-${var.stack_id}-name" = var.bucket_name "x-nitric-${var.stack_id}-type" = "bucket" } + + dynamic "cors" { + for_each = var.cors_rules + content { + origin = cors.value.allowed_origins + method = cors.value.allowed_methods + response_header = cors.value.expose_headers + max_age_seconds = cors.value.max_age_seconds + } + } } locals { diff --git a/cloud/gcp/deploytf/.nitric/modules/bucket/variables.tf b/cloud/gcp/deploytf/.nitric/modules/bucket/variables.tf index a9728bf1f..eb49df3a9 100644 --- a/cloud/gcp/deploytf/.nitric/modules/bucket/variables.tf +++ b/cloud/gcp/deploytf/.nitric/modules/bucket/variables.tf @@ -24,4 +24,15 @@ variable "storage_class" { description = "The class of storage used to store the bucket's contents. This can be STANDARD, NEARLINE, COLDLINE, ARCHIVE, or MULTI_REGIONAL." type = string default = "STANDARD" +} + +variable "cors_rules" { + description = "CORS rules for the bucket" + type = list(object({ + allowed_origins = list(string) + allowed_methods = list(string) + expose_headers = list(string) + max_age_seconds = number + })) + default = [] } \ No newline at end of file diff --git a/cloud/gcp/deploytf/bucket.go b/cloud/gcp/deploytf/bucket.go index a7de23e4b..587e530c3 100644 --- a/cloud/gcp/deploytf/bucket.go +++ b/cloud/gcp/deploytf/bucket.go @@ -19,6 +19,7 @@ import ( "github.com/hashicorp/terraform-cdk-go/cdktf" "github.com/nitrictech/nitric/cloud/gcp/deploytf/generated/bucket" deploymentspb "github.com/nitrictech/nitric/core/pkg/proto/deployments/v1" + "github.com/nitrictech/nitric/core/pkg/logger" storagepb "github.com/nitrictech/nitric/core/pkg/proto/storage/v1" ) @@ -62,10 +63,28 @@ func (n *NitricGcpTerraformProvider) Bucket(stack cdktf.TerraformStack, name str } } + var corsRules []map[string]interface{} + warnedAllowedHeaders := false + for _, rule := range config.CorsRules { + if len(rule.AllowedHeaders) > 0 && !warnedAllowedHeaders { + logger.Warnf("bucket %q: GCP Cloud Storage does not support AllowedHeaders in CORS configuration. "+ + "GCS automatically allows all request headers when the origin and method match. "+ + "The AllowedHeaders setting will be ignored.", name) + warnedAllowedHeaders = true + } + corsRules = append(corsRules, map[string]interface{}{ + "allowed_origins": jsii.Strings(rule.AllowedOrigins...), + "allowed_methods": jsii.Strings(rule.AllowedMethods...), + "expose_headers": jsii.Strings(rule.ExposeHeaders...), + "max_age_seconds": jsii.Number(float64(rule.MaxAgeSeconds)), + }) + } + n.Buckets[name] = bucket.NewBucket(stack, jsii.Sprintf("bucket_%s", name), &bucket.BucketConfig{ BucketName: &name, StackId: n.Stack.StackIdOutput(), NotificationTargets: ¬ificationTargets, + CorsRules: &corsRules, }) return nil diff --git a/cloud/gcp/deploytf/generated/api/jsii/api-0.0.0.tgz b/cloud/gcp/deploytf/generated/api/jsii/api-0.0.0.tgz index 36d403da8..68da2927a 100644 Binary files a/cloud/gcp/deploytf/generated/api/jsii/api-0.0.0.tgz and b/cloud/gcp/deploytf/generated/api/jsii/api-0.0.0.tgz differ diff --git a/cloud/gcp/deploytf/generated/bucket/Bucket.go b/cloud/gcp/deploytf/generated/bucket/Bucket.go index 439b43948..72e6d25d5 100644 --- a/cloud/gcp/deploytf/generated/bucket/Bucket.go +++ b/cloud/gcp/deploytf/generated/bucket/Bucket.go @@ -22,6 +22,8 @@ type Bucket interface { CdktfStack() cdktf.TerraformStack // Experimental. ConstructNodeMetadata() *map[string]interface{} + CorsRules() interface{} + SetCorsRules(val interface{}) // Experimental. DependsOn() *[]*string // Experimental. @@ -134,6 +136,16 @@ func (j *jsiiProxy_Bucket) ConstructNodeMetadata() *map[string]interface{} { return returns } +func (j *jsiiProxy_Bucket) CorsRules() interface{} { + var returns interface{} + _jsii_.Get( + j, + "corsRules", + &returns, + ) + return returns +} + func (j *jsiiProxy_Bucket) DependsOn() *[]*string { var returns *[]*string _jsii_.Get( @@ -313,6 +325,17 @@ func (j *jsiiProxy_Bucket)SetBucketName(val *string) { ) } +func (j *jsiiProxy_Bucket)SetCorsRules(val interface{}) { + if err := j.validateSetCorsRulesParameters(val); err != nil { + panic(err) + } + _jsii_.Set( + j, + "corsRules", + val, + ) +} + func (j *jsiiProxy_Bucket)SetDependsOn(val *[]*string) { _jsii_.Set( j, diff --git a/cloud/gcp/deploytf/generated/bucket/BucketConfig.go b/cloud/gcp/deploytf/generated/bucket/BucketConfig.go index a370aa076..cc58daf27 100644 --- a/cloud/gcp/deploytf/generated/bucket/BucketConfig.go +++ b/cloud/gcp/deploytf/generated/bucket/BucketConfig.go @@ -19,6 +19,8 @@ type BucketConfig struct { NotificationTargets interface{} `field:"required" json:"notificationTargets" yaml:"notificationTargets"` // The ID of the Nitric stack. StackId *string `field:"required" json:"stackId" yaml:"stackId"` + // CORS rules for the bucket. + CorsRules interface{} `field:"optional" json:"corsRules" yaml:"corsRules"` // The class of storage used to store the bucket's contents. // // This can be STANDARD, NEARLINE, COLDLINE, ARCHIVE, or MULTI_REGIONAL. diff --git a/cloud/gcp/deploytf/generated/bucket/Bucket__checks.go b/cloud/gcp/deploytf/generated/bucket/Bucket__checks.go index b1fd8a491..c4a8a96b1 100644 --- a/cloud/gcp/deploytf/generated/bucket/Bucket__checks.go +++ b/cloud/gcp/deploytf/generated/bucket/Bucket__checks.go @@ -98,6 +98,14 @@ func (j *jsiiProxy_Bucket) validateSetBucketNameParameters(val *string) error { return nil } +func (j *jsiiProxy_Bucket) validateSetCorsRulesParameters(val interface{}) error { + if val == nil { + return fmt.Errorf("parameter val is required, but nil was provided") + } + + return nil +} + func (j *jsiiProxy_Bucket) validateSetNotificationTargetsParameters(val interface{}) error { if val == nil { return fmt.Errorf("parameter val is required, but nil was provided") diff --git a/cloud/gcp/deploytf/generated/bucket/Bucket__no_checks.go b/cloud/gcp/deploytf/generated/bucket/Bucket__no_checks.go index f13b5347c..c4b42ed83 100644 --- a/cloud/gcp/deploytf/generated/bucket/Bucket__no_checks.go +++ b/cloud/gcp/deploytf/generated/bucket/Bucket__no_checks.go @@ -36,6 +36,10 @@ func (j *jsiiProxy_Bucket) validateSetBucketNameParameters(val *string) error { return nil } +func (j *jsiiProxy_Bucket) validateSetCorsRulesParameters(val interface{}) error { + return nil +} + func (j *jsiiProxy_Bucket) validateSetNotificationTargetsParameters(val interface{}) error { return nil } diff --git a/cloud/gcp/deploytf/generated/bucket/jsii/bucket-0.0.0.tgz b/cloud/gcp/deploytf/generated/bucket/jsii/bucket-0.0.0.tgz index 44998d628..7e2e4fbc5 100644 Binary files a/cloud/gcp/deploytf/generated/bucket/jsii/bucket-0.0.0.tgz and b/cloud/gcp/deploytf/generated/bucket/jsii/bucket-0.0.0.tgz differ diff --git a/cloud/gcp/deploytf/generated/bucket/main.go b/cloud/gcp/deploytf/generated/bucket/main.go index 34050b931..372ea248a 100644 --- a/cloud/gcp/deploytf/generated/bucket/main.go +++ b/cloud/gcp/deploytf/generated/bucket/main.go @@ -19,6 +19,7 @@ func init() { _jsii_.MemberProperty{JsiiProperty: "bucketStorageClassOutput", GoGetter: "BucketStorageClassOutput"}, _jsii_.MemberProperty{JsiiProperty: "cdktfStack", GoGetter: "CdktfStack"}, _jsii_.MemberProperty{JsiiProperty: "constructNodeMetadata", GoGetter: "ConstructNodeMetadata"}, + _jsii_.MemberProperty{JsiiProperty: "corsRules", GoGetter: "CorsRules"}, _jsii_.MemberProperty{JsiiProperty: "dependsOn", GoGetter: "DependsOn"}, _jsii_.MemberProperty{JsiiProperty: "forEach", GoGetter: "ForEach"}, _jsii_.MemberProperty{JsiiProperty: "fqn", GoGetter: "Fqn"}, diff --git a/cloud/gcp/deploytf/generated/cdn/jsii/cdn-0.0.0.tgz b/cloud/gcp/deploytf/generated/cdn/jsii/cdn-0.0.0.tgz index c8c27a57f..cd5b215fb 100644 Binary files a/cloud/gcp/deploytf/generated/cdn/jsii/cdn-0.0.0.tgz and b/cloud/gcp/deploytf/generated/cdn/jsii/cdn-0.0.0.tgz differ diff --git a/cloud/gcp/deploytf/generated/http_proxy/jsii/http_proxy-0.0.0.tgz b/cloud/gcp/deploytf/generated/http_proxy/jsii/http_proxy-0.0.0.tgz index 417e84828..7412b79c4 100644 Binary files a/cloud/gcp/deploytf/generated/http_proxy/jsii/http_proxy-0.0.0.tgz and b/cloud/gcp/deploytf/generated/http_proxy/jsii/http_proxy-0.0.0.tgz differ diff --git a/cloud/gcp/deploytf/generated/policy/jsii/policy-0.0.0.tgz b/cloud/gcp/deploytf/generated/policy/jsii/policy-0.0.0.tgz index 6359fad72..21a3bfbbd 100644 Binary files a/cloud/gcp/deploytf/generated/policy/jsii/policy-0.0.0.tgz and b/cloud/gcp/deploytf/generated/policy/jsii/policy-0.0.0.tgz differ diff --git a/cloud/gcp/deploytf/generated/queue/jsii/queue-0.0.0.tgz b/cloud/gcp/deploytf/generated/queue/jsii/queue-0.0.0.tgz index d38ffc7f8..66c1f39b2 100644 Binary files a/cloud/gcp/deploytf/generated/queue/jsii/queue-0.0.0.tgz and b/cloud/gcp/deploytf/generated/queue/jsii/queue-0.0.0.tgz differ diff --git a/cloud/gcp/deploytf/generated/schedule/jsii/schedule-0.0.0.tgz b/cloud/gcp/deploytf/generated/schedule/jsii/schedule-0.0.0.tgz index 73c444eb2..1916a8114 100644 Binary files a/cloud/gcp/deploytf/generated/schedule/jsii/schedule-0.0.0.tgz and b/cloud/gcp/deploytf/generated/schedule/jsii/schedule-0.0.0.tgz differ diff --git a/cloud/gcp/deploytf/generated/secret/jsii/secret-0.0.0.tgz b/cloud/gcp/deploytf/generated/secret/jsii/secret-0.0.0.tgz index 9ab635bdd..e9bb9c3a4 100644 Binary files a/cloud/gcp/deploytf/generated/secret/jsii/secret-0.0.0.tgz and b/cloud/gcp/deploytf/generated/secret/jsii/secret-0.0.0.tgz differ diff --git a/cloud/gcp/deploytf/generated/service/jsii/service-0.0.0.tgz b/cloud/gcp/deploytf/generated/service/jsii/service-0.0.0.tgz index 387555cdb..182eecafe 100644 Binary files a/cloud/gcp/deploytf/generated/service/jsii/service-0.0.0.tgz and b/cloud/gcp/deploytf/generated/service/jsii/service-0.0.0.tgz differ diff --git a/cloud/gcp/deploytf/generated/stack/jsii/stack-0.0.0.tgz b/cloud/gcp/deploytf/generated/stack/jsii/stack-0.0.0.tgz index b31e8652d..be6ad1479 100644 Binary files a/cloud/gcp/deploytf/generated/stack/jsii/stack-0.0.0.tgz and b/cloud/gcp/deploytf/generated/stack/jsii/stack-0.0.0.tgz differ diff --git a/cloud/gcp/deploytf/generated/topic/jsii/topic-0.0.0.tgz b/cloud/gcp/deploytf/generated/topic/jsii/topic-0.0.0.tgz index e7887a566..c8a5179d8 100644 Binary files a/cloud/gcp/deploytf/generated/topic/jsii/topic-0.0.0.tgz and b/cloud/gcp/deploytf/generated/topic/jsii/topic-0.0.0.tgz differ diff --git a/cloud/gcp/deploytf/generated/website/jsii/website-0.0.0.tgz b/cloud/gcp/deploytf/generated/website/jsii/website-0.0.0.tgz index 2cdf8c193..a685b3b79 100644 Binary files a/cloud/gcp/deploytf/generated/website/jsii/website-0.0.0.tgz and b/cloud/gcp/deploytf/generated/website/jsii/website-0.0.0.tgz differ diff --git a/core/pkg/proto/deployments/v1/deployments.pb.go b/core/pkg/proto/deployments/v1/deployments.pb.go index 8f53e12da..672ebf6ca 100644 --- a/core/pkg/proto/deployments/v1/deployments.pb.go +++ b/core/pkg/proto/deployments/v1/deployments.pb.go @@ -993,18 +993,104 @@ type Batch_Image struct { func (*Batch_Image) isBatch_Source() {} +// CORS rule configuration for a storage bucket. +type BucketCorsRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Origins allowed to make cross-origin requests (e.g., "https://example.com"). + AllowedOrigins []string `protobuf:"bytes,1,rep,name=allowed_origins,json=allowedOrigins,proto3" json:"allowed_origins,omitempty"` + // HTTP methods allowed for cross-origin requests (e.g., "GET", "PUT"). + AllowedMethods []string `protobuf:"bytes,2,rep,name=allowed_methods,json=allowedMethods,proto3" json:"allowed_methods,omitempty"` + // Request headers allowed in preflight requests. Not supported by all providers. + AllowedHeaders []string `protobuf:"bytes,3,rep,name=allowed_headers,json=allowedHeaders,proto3" json:"allowed_headers,omitempty"` + // Response headers exposed to the browser. + ExposeHeaders []string `protobuf:"bytes,4,rep,name=expose_headers,json=exposeHeaders,proto3" json:"expose_headers,omitempty"` + // Maximum time in seconds a preflight response can be cached. Omit or set to 0 for provider default. + MaxAgeSeconds int32 `protobuf:"varint,5,opt,name=max_age_seconds,json=maxAgeSeconds,proto3" json:"max_age_seconds,omitempty"` +} + +func (x *BucketCorsRule) Reset() { + *x = BucketCorsRule{} + if protoimpl.UnsafeEnabled { + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BucketCorsRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BucketCorsRule) ProtoMessage() {} + +func (x *BucketCorsRule) ProtoReflect() protoreflect.Message { + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BucketCorsRule.ProtoReflect.Descriptor instead. +func (*BucketCorsRule) Descriptor() ([]byte, []int) { + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{11} +} + +func (x *BucketCorsRule) GetAllowedOrigins() []string { + if x != nil { + return x.AllowedOrigins + } + return nil +} + +func (x *BucketCorsRule) GetAllowedMethods() []string { + if x != nil { + return x.AllowedMethods + } + return nil +} + +func (x *BucketCorsRule) GetAllowedHeaders() []string { + if x != nil { + return x.AllowedHeaders + } + return nil +} + +func (x *BucketCorsRule) GetExposeHeaders() []string { + if x != nil { + return x.ExposeHeaders + } + return nil +} + +func (x *BucketCorsRule) GetMaxAgeSeconds() int32 { + if x != nil { + return x.MaxAgeSeconds + } + return 0 +} + type Bucket struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Listeners []*BucketListener `protobuf:"bytes,1,rep,name=listeners,proto3" json:"listeners,omitempty"` + CorsRules []*BucketCorsRule `protobuf:"bytes,2,rep,name=cors_rules,json=corsRules,proto3" json:"cors_rules,omitempty"` } func (x *Bucket) Reset() { *x = Bucket{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[11] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1017,7 +1103,7 @@ func (x *Bucket) String() string { func (*Bucket) ProtoMessage() {} func (x *Bucket) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[11] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1030,7 +1116,7 @@ func (x *Bucket) ProtoReflect() protoreflect.Message { // Deprecated: Use Bucket.ProtoReflect.Descriptor instead. func (*Bucket) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{11} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{12} } func (x *Bucket) GetListeners() []*BucketListener { @@ -1040,6 +1126,13 @@ func (x *Bucket) GetListeners() []*BucketListener { return nil } +func (x *Bucket) GetCorsRules() []*BucketCorsRule { + if x != nil { + return x.CorsRules + } + return nil +} + type BucketListener struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1055,7 +1148,7 @@ type BucketListener struct { func (x *BucketListener) Reset() { *x = BucketListener{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[12] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1068,7 +1161,7 @@ func (x *BucketListener) String() string { func (*BucketListener) ProtoMessage() {} func (x *BucketListener) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[12] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1081,7 +1174,7 @@ func (x *BucketListener) ProtoReflect() protoreflect.Message { // Deprecated: Use BucketListener.ProtoReflect.Descriptor instead. func (*BucketListener) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{12} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{13} } func (x *BucketListener) GetConfig() *v12.RegistrationRequest { @@ -1127,7 +1220,7 @@ type Topic struct { func (x *Topic) Reset() { *x = Topic{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[13] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1140,7 +1233,7 @@ func (x *Topic) String() string { func (*Topic) ProtoMessage() {} func (x *Topic) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[13] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1153,7 +1246,7 @@ func (x *Topic) ProtoReflect() protoreflect.Message { // Deprecated: Use Topic.ProtoReflect.Descriptor instead. func (*Topic) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{13} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{14} } func (x *Topic) GetSubscriptions() []*SubscriptionTarget { @@ -1172,7 +1265,7 @@ type Queue struct { func (x *Queue) Reset() { *x = Queue{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[14] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1185,7 +1278,7 @@ func (x *Queue) String() string { func (*Queue) ProtoMessage() {} func (x *Queue) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[14] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1198,7 +1291,7 @@ func (x *Queue) ProtoReflect() protoreflect.Message { // Deprecated: Use Queue.ProtoReflect.Descriptor instead. func (*Queue) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{14} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{15} } type KeyValueStore struct { @@ -1210,7 +1303,7 @@ type KeyValueStore struct { func (x *KeyValueStore) Reset() { *x = KeyValueStore{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[15] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1223,7 +1316,7 @@ func (x *KeyValueStore) String() string { func (*KeyValueStore) ProtoMessage() {} func (x *KeyValueStore) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[15] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1236,7 +1329,7 @@ func (x *KeyValueStore) ProtoReflect() protoreflect.Message { // Deprecated: Use KeyValueStore.ProtoReflect.Descriptor instead. func (*KeyValueStore) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{15} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{16} } type Secret struct { @@ -1248,7 +1341,7 @@ type Secret struct { func (x *Secret) Reset() { *x = Secret{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[16] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1261,7 +1354,7 @@ func (x *Secret) String() string { func (*Secret) ProtoMessage() {} func (x *Secret) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[16] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1274,7 +1367,7 @@ func (x *Secret) ProtoReflect() protoreflect.Message { // Deprecated: Use Secret.ProtoReflect.Descriptor instead. func (*Secret) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{16} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{17} } type SubscriptionTarget struct { @@ -1291,7 +1384,7 @@ type SubscriptionTarget struct { func (x *SubscriptionTarget) Reset() { *x = SubscriptionTarget{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[17] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1304,7 +1397,7 @@ func (x *SubscriptionTarget) String() string { func (*SubscriptionTarget) ProtoMessage() {} func (x *SubscriptionTarget) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[17] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1317,7 +1410,7 @@ func (x *SubscriptionTarget) ProtoReflect() protoreflect.Message { // Deprecated: Use SubscriptionTarget.ProtoReflect.Descriptor instead. func (*SubscriptionTarget) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{17} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{18} } func (m *SubscriptionTarget) GetTarget() isSubscriptionTarget_Target { @@ -1356,7 +1449,7 @@ type TopicSubscription struct { func (x *TopicSubscription) Reset() { *x = TopicSubscription{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[18] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1369,7 +1462,7 @@ func (x *TopicSubscription) String() string { func (*TopicSubscription) ProtoMessage() {} func (x *TopicSubscription) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[18] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1382,7 +1475,7 @@ func (x *TopicSubscription) ProtoReflect() protoreflect.Message { // Deprecated: Use TopicSubscription.ProtoReflect.Descriptor instead. func (*TopicSubscription) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{18} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{19} } func (x *TopicSubscription) GetTarget() *SubscriptionTarget { @@ -1406,7 +1499,7 @@ type HttpTarget struct { func (x *HttpTarget) Reset() { *x = HttpTarget{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[19] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1419,7 +1512,7 @@ func (x *HttpTarget) String() string { func (*HttpTarget) ProtoMessage() {} func (x *HttpTarget) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[19] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1432,7 +1525,7 @@ func (x *HttpTarget) ProtoReflect() protoreflect.Message { // Deprecated: Use HttpTarget.ProtoReflect.Descriptor instead. func (*HttpTarget) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{19} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{20} } func (m *HttpTarget) GetTarget() isHttpTarget_Target { @@ -1472,7 +1565,7 @@ type Http struct { func (x *Http) Reset() { *x = Http{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[20] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1485,7 +1578,7 @@ func (x *Http) String() string { func (*Http) ProtoMessage() {} func (x *Http) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[20] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1498,7 +1591,7 @@ func (x *Http) ProtoReflect() protoreflect.Message { // Deprecated: Use Http.ProtoReflect.Descriptor instead. func (*Http) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{20} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{21} } func (x *Http) GetTarget() *HttpTarget { @@ -1522,7 +1615,7 @@ type Api struct { func (x *Api) Reset() { *x = Api{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[21] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1535,7 +1628,7 @@ func (x *Api) String() string { func (*Api) ProtoMessage() {} func (x *Api) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[21] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1548,7 +1641,7 @@ func (x *Api) ProtoReflect() protoreflect.Message { // Deprecated: Use Api.ProtoReflect.Descriptor instead. func (*Api) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{21} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{22} } func (m *Api) GetDocument() isApi_Document { @@ -1594,7 +1687,7 @@ type Websocket struct { func (x *Websocket) Reset() { *x = Websocket{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[22] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1607,7 +1700,7 @@ func (x *Websocket) String() string { func (*Websocket) ProtoMessage() {} func (x *Websocket) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[22] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1620,7 +1713,7 @@ func (x *Websocket) ProtoReflect() protoreflect.Message { // Deprecated: Use Websocket.ProtoReflect.Descriptor instead. func (*Websocket) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{22} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{23} } func (x *Websocket) GetConnectTarget() *WebsocketTarget { @@ -1658,7 +1751,7 @@ type WebsocketTarget struct { func (x *WebsocketTarget) Reset() { *x = WebsocketTarget{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[23] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1671,7 +1764,7 @@ func (x *WebsocketTarget) String() string { func (*WebsocketTarget) ProtoMessage() {} func (x *WebsocketTarget) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[23] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1684,7 +1777,7 @@ func (x *WebsocketTarget) ProtoReflect() protoreflect.Message { // Deprecated: Use WebsocketTarget.ProtoReflect.Descriptor instead. func (*WebsocketTarget) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{23} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{24} } func (m *WebsocketTarget) GetTarget() isWebsocketTarget_Target { @@ -1734,7 +1827,7 @@ type Website struct { func (x *Website) Reset() { *x = Website{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[24] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1747,7 +1840,7 @@ func (x *Website) String() string { func (*Website) ProtoMessage() {} func (x *Website) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[24] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1760,7 +1853,7 @@ func (x *Website) ProtoReflect() protoreflect.Message { // Deprecated: Use Website.ProtoReflect.Descriptor instead. func (*Website) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{24} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{25} } func (x *Website) GetIndexDocument() string { @@ -1823,7 +1916,7 @@ type ScheduleTarget struct { func (x *ScheduleTarget) Reset() { *x = ScheduleTarget{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[25] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1836,7 +1929,7 @@ func (x *ScheduleTarget) String() string { func (*ScheduleTarget) ProtoMessage() {} func (x *ScheduleTarget) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[25] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1849,7 +1942,7 @@ func (x *ScheduleTarget) ProtoReflect() protoreflect.Message { // Deprecated: Use ScheduleTarget.ProtoReflect.Descriptor instead. func (*ScheduleTarget) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{25} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{26} } func (m *ScheduleTarget) GetTarget() isScheduleTarget_Target { @@ -1893,7 +1986,7 @@ type Schedule struct { func (x *Schedule) Reset() { *x = Schedule{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[26] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1906,7 +1999,7 @@ func (x *Schedule) String() string { func (*Schedule) ProtoMessage() {} func (x *Schedule) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[26] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1919,7 +2012,7 @@ func (x *Schedule) ProtoReflect() protoreflect.Message { // Deprecated: Use Schedule.ProtoReflect.Descriptor instead. func (*Schedule) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{26} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{27} } func (x *Schedule) GetTarget() *ScheduleTarget { @@ -1980,7 +2073,7 @@ type SqlDatabase struct { func (x *SqlDatabase) Reset() { *x = SqlDatabase{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[27] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1993,7 +2086,7 @@ func (x *SqlDatabase) String() string { func (*SqlDatabase) ProtoMessage() {} func (x *SqlDatabase) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[27] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2006,7 +2099,7 @@ func (x *SqlDatabase) ProtoReflect() protoreflect.Message { // Deprecated: Use SqlDatabase.ProtoReflect.Descriptor instead. func (*SqlDatabase) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{27} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{28} } func (m *SqlDatabase) GetMigrations() isSqlDatabase_Migrations { @@ -2046,7 +2139,7 @@ type ScheduleEvery struct { func (x *ScheduleEvery) Reset() { *x = ScheduleEvery{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[28] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2059,7 +2152,7 @@ func (x *ScheduleEvery) String() string { func (*ScheduleEvery) ProtoMessage() {} func (x *ScheduleEvery) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[28] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2072,7 +2165,7 @@ func (x *ScheduleEvery) ProtoReflect() protoreflect.Message { // Deprecated: Use ScheduleEvery.ProtoReflect.Descriptor instead. func (*ScheduleEvery) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{28} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{29} } func (x *ScheduleEvery) GetRate() string { @@ -2094,7 +2187,7 @@ type ScheduleCron struct { func (x *ScheduleCron) Reset() { *x = ScheduleCron{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[29] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2107,7 +2200,7 @@ func (x *ScheduleCron) String() string { func (*ScheduleCron) ProtoMessage() {} func (x *ScheduleCron) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[29] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2120,7 +2213,7 @@ func (x *ScheduleCron) ProtoReflect() protoreflect.Message { // Deprecated: Use ScheduleCron.ProtoReflect.Descriptor instead. func (*ScheduleCron) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{29} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{30} } func (x *ScheduleCron) GetExpression() string { @@ -2158,7 +2251,7 @@ type Resource struct { func (x *Resource) Reset() { *x = Resource{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[30] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2171,7 +2264,7 @@ func (x *Resource) String() string { func (*Resource) ProtoMessage() {} func (x *Resource) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[30] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2184,7 +2277,7 @@ func (x *Resource) ProtoReflect() protoreflect.Message { // Deprecated: Use Resource.ProtoReflect.Descriptor instead. func (*Resource) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{30} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{31} } func (x *Resource) GetId() *v1.ResourceIdentifier { @@ -2402,7 +2495,7 @@ type Policy struct { func (x *Policy) Reset() { *x = Policy{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[31] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2415,7 +2508,7 @@ func (x *Policy) String() string { func (*Policy) ProtoMessage() {} func (x *Policy) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[31] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2428,7 +2521,7 @@ func (x *Policy) ProtoReflect() protoreflect.Message { // Deprecated: Use Policy.ProtoReflect.Descriptor instead. func (*Policy) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{31} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{32} } func (x *Policy) GetPrincipals() []*Resource { @@ -2464,7 +2557,7 @@ type Spec struct { func (x *Spec) Reset() { *x = Spec{} if protoimpl.UnsafeEnabled { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[32] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2477,7 +2570,7 @@ func (x *Spec) String() string { func (*Spec) ProtoMessage() {} func (x *Spec) ProtoReflect() protoreflect.Message { - mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[32] + mi := &file_nitric_proto_deployments_v1_deployments_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2490,7 +2583,7 @@ func (x *Spec) ProtoReflect() protoreflect.Message { // Deprecated: Use Spec.ProtoReflect.Descriptor instead. func (*Spec) Descriptor() ([]byte, []int) { - return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{32} + return file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP(), []int{33} } func (x *Spec) GetResources() []*Resource { @@ -2629,226 +2722,245 @@ var file_nitric_proto_deployments_v1_deployments_proto_rawDesc = []byte{ 0x6e, 0x76, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x53, 0x0a, - 0x06, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x49, 0x0a, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x65, - 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6e, 0x69, 0x74, + 0x02, 0x38, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0xda, 0x01, + 0x0a, 0x0e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x72, 0x73, 0x52, 0x75, 0x6c, 0x65, + 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x65, 0x64, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x6c, 0x6c, + 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x6c, 0x6c, + 0x6f, 0x77, 0x65, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, + 0x78, 0x70, 0x6f, 0x73, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, + 0x41, 0x67, 0x65, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x9f, 0x01, 0x0a, 0x06, 0x42, + 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x49, 0x0a, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, + 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x4c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, + 0x12, 0x4a, 0x0a, 0x0a, 0x63, 0x6f, 0x72, 0x73, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x72, 0x73, 0x52, 0x75, 0x6c, + 0x65, 0x52, 0x09, 0x63, 0x6f, 0x72, 0x73, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x7c, 0x0a, 0x0e, + 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x44, + 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, + 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x06, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x42, 0x08, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x5e, 0x0a, 0x05, 0x54, 0x6f, + 0x70, 0x69, 0x63, 0x12, 0x55, 0x0a, 0x0d, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x4c, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, - 0x72, 0x73, 0x22, 0x7c, 0x0a, 0x0e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x4c, 0x69, 0x73, 0x74, - 0x65, 0x6e, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x07, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x22, 0x5e, 0x0a, 0x05, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x55, 0x0a, 0x0d, 0x73, 0x75, 0x62, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2f, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x22, 0x07, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x75, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x4b, 0x65, 0x79, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x08, 0x0a, 0x06, 0x53, 0x65, - 0x63, 0x72, 0x65, 0x74, 0x22, 0x3a, 0x0a, 0x12, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x07, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x22, 0x5c, 0x0a, 0x11, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x32, - 0x0a, 0x0a, 0x48, 0x74, 0x74, 0x70, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x07, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, - 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x22, 0x47, 0x0a, 0x04, 0x48, 0x74, 0x74, 0x70, 0x12, 0x3f, 0x0a, 0x06, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6e, 0x69, 0x74, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x0d, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x07, 0x0a, 0x05, 0x51, 0x75, + 0x65, 0x75, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0x22, 0x08, 0x0a, 0x06, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x3a, + 0x0a, 0x12, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x42, 0x08, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x5c, 0x0a, 0x11, 0x54, 0x6f, + 0x70, 0x69, 0x63, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x47, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2f, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, + 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x32, 0x0a, 0x0a, 0x48, 0x74, 0x74, 0x70, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x47, 0x0a, 0x04, + 0x48, 0x74, 0x74, 0x70, 0x12, 0x3f, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x2d, 0x0a, 0x03, 0x41, 0x70, 0x69, 0x12, 0x1a, 0x0a, 0x07, + 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x07, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x42, 0x0a, 0x0a, 0x08, 0x64, 0x6f, 0x63, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x90, 0x02, 0x0a, 0x09, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, + 0x65, 0x74, 0x12, 0x53, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x54, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x2d, 0x0a, 0x03, 0x41, - 0x70, 0x69, 0x12, 0x1a, 0x0a, 0x07, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x42, 0x0a, - 0x0a, 0x08, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x90, 0x02, 0x0a, 0x09, 0x57, - 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x53, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2c, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x57, - 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x0d, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x59, 0x0a, - 0x11, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, - 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, - 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x10, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x53, 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2c, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x57, - 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x0d, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x37, 0x0a, - 0x0f, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x12, 0x1a, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x08, 0x0a, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0xaf, 0x01, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x73, 0x69, - 0x74, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x64, 0x6f, 0x63, 0x75, - 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x5f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x61, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x29, 0x0a, - 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x44, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x0e, 0x0a, 0x0c, 0x61, 0x73, 0x73, 0x65, - 0x74, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x36, 0x0a, 0x0e, 0x53, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x07, 0x73, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, + 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x59, 0x0a, 0x11, 0x64, 0x69, 0x73, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, + 0x2e, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x52, 0x10, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x12, 0x53, 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6e, 0x69, 0x74, + 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, + 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x37, 0x0a, 0x0f, 0x57, 0x65, 0x62, 0x73, 0x6f, + 0x63, 0x6b, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x22, 0xdf, 0x01, 0x0a, 0x08, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x43, 0x0a, - 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, - 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, - 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x12, 0x42, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x72, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2a, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, - 0x05, 0x65, 0x76, 0x65, 0x72, 0x79, 0x12, 0x3f, 0x0a, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x48, - 0x00, 0x52, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x63, 0x61, 0x64, 0x65, 0x6e, - 0x63, 0x65, 0x22, 0x3a, 0x0a, 0x0b, 0x53, 0x71, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x12, 0x1d, 0x0a, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x55, 0x72, 0x69, - 0x42, 0x0c, 0x0a, 0x0a, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x23, - 0x0a, 0x0d, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x72, 0x79, 0x12, - 0x12, 0x0a, 0x04, 0x72, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, - 0x61, 0x74, 0x65, 0x22, 0x2e, 0x0a, 0x0c, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x43, - 0x72, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x22, 0xe9, 0x07, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x12, 0x3d, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6e, - 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x40, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x24, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x48, 0x00, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x48, 0x00, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, - 0x12, 0x3a, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x22, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, - 0x70, 0x69, 0x63, 0x48, 0x00, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x34, 0x0a, 0x03, - 0x61, 0x70, 0x69, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6e, 0x69, 0x74, 0x72, + 0x22, 0xaf, 0x01, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x25, 0x0a, 0x0e, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x44, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x64, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x61, + 0x73, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, + 0x61, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x29, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x79, 0x42, 0x0e, 0x0a, 0x0c, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x22, 0x36, 0x0a, 0x0e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x42, 0x08, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0xdf, 0x01, 0x0a, 0x08, 0x53, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x42, 0x0a, 0x05, + 0x65, 0x76, 0x65, 0x72, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x6e, 0x69, + 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, + 0x6c, 0x65, 0x45, 0x76, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, 0x05, 0x65, 0x76, 0x65, 0x72, 0x79, + 0x12, 0x3f, 0x0a, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, + 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, + 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x04, 0x63, 0x72, 0x6f, + 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x63, 0x61, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x0a, 0x0b, + 0x53, 0x71, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x09, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x08, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x55, 0x72, 0x69, 0x42, 0x0c, 0x0a, 0x0a, 0x6d, 0x69, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x23, 0x0a, 0x0d, 0x53, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x61, 0x74, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x61, 0x74, 0x65, 0x22, 0x2e, 0x0a, + 0x0c, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, + 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xe9, 0x07, + 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x3d, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x02, 0x69, 0x64, 0x12, 0x40, 0x0a, 0x07, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x69, 0x74, + 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x48, 0x00, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x62, + 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x69, + 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, + 0x48, 0x00, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x3a, 0x0a, 0x05, 0x74, 0x6f, + 0x70, 0x69, 0x63, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x70, 0x69, 0x48, 0x00, 0x52, 0x03, 0x61, - 0x70, 0x69, 0x12, 0x3d, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x0e, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x12, 0x43, 0x0a, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x0f, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x48, 0x00, 0x52, + 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x34, 0x0a, 0x03, 0x61, 0x70, 0x69, 0x18, 0x0d, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x08, 0x73, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2a, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, - 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x6b, - 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x3d, 0x0a, 0x06, - 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, + 0x31, 0x2e, 0x41, 0x70, 0x69, 0x48, 0x00, 0x52, 0x03, 0x61, 0x70, 0x69, 0x12, 0x3d, 0x0a, 0x06, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, - 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, - 0x74, 0x48, 0x00, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x46, 0x0a, 0x09, 0x77, - 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, + 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x48, 0x00, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x43, 0x0a, 0x08, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, + 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, + 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, + 0x12, 0x54, 0x0a, 0x0f, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x6e, 0x69, 0x74, 0x72, + 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x53, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x48, 0x00, 0x52, 0x06, 0x73, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x46, 0x0a, 0x09, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, + 0x65, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, + 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, + 0x48, 0x00, 0x52, 0x09, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x37, 0x0a, + 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6e, 0x69, + 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x48, 0x00, + 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x3a, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x75, 0x65, 0x18, + 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x75, 0x65, 0x48, 0x00, 0x52, 0x05, 0x71, 0x75, 0x65, + 0x75, 0x65, 0x12, 0x4d, 0x0a, 0x0c, 0x73, 0x71, 0x6c, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, + 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x71, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x71, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x12, 0x3a, 0x0a, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x22, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x48, 0x00, 0x52, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x12, 0x40, 0x0a, + 0x07, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x65, 0x62, - 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x48, 0x00, 0x52, 0x09, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, - 0x6b, 0x65, 0x74, 0x12, 0x37, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x13, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x21, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x48, 0x74, 0x74, 0x70, 0x48, 0x00, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x3a, 0x0a, 0x05, - 0x71, 0x75, 0x65, 0x75, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6e, 0x69, + 0x73, 0x69, 0x74, 0x65, 0x48, 0x00, 0x52, 0x07, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x42, + 0x08, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xd1, 0x01, 0x0a, 0x06, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x12, 0x45, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, + 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, + 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x3b, 0x0a, 0x07, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x6e, + 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x75, 0x65, 0x48, - 0x00, 0x52, 0x05, 0x71, 0x75, 0x65, 0x75, 0x65, 0x12, 0x4d, 0x0a, 0x0c, 0x73, 0x71, 0x6c, 0x5f, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, - 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, - 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x71, 0x6c, - 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x71, 0x6c, 0x44, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, - 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x48, 0x00, 0x52, 0x05, 0x62, 0x61, - 0x74, 0x63, 0x68, 0x12, 0x40, 0x0a, 0x07, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x18, 0x17, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x48, 0x00, 0x52, 0x07, 0x77, 0x65, - 0x62, 0x73, 0x69, 0x74, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, - 0xd1, 0x01, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x45, 0x0a, 0x0a, 0x70, 0x72, - 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, - 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, - 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, - 0x73, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, - 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x25, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x22, 0x4b, 0x0a, 0x04, 0x53, 0x70, 0x65, 0x63, 0x12, 0x43, 0x0a, 0x09, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, - 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, - 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x2a, 0x55, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x70, 0x6c, - 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, - 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, - 0x54, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x10, - 0x02, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x41, 0x4d, 0x45, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x44, - 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x04, 0x2a, 0x51, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x00, - 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, - 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x0a, - 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x32, 0xe6, 0x01, 0x0a, 0x0a, 0x44, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x68, 0x0a, 0x02, 0x55, 0x70, 0x12, - 0x30, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, - 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2e, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x30, 0x01, 0x12, 0x6e, 0x0a, 0x04, 0x44, 0x6f, 0x77, 0x6e, 0x12, 0x32, 0x2e, 0x6e, 0x69, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x4b, 0x0a, + 0x04, 0x53, 0x70, 0x65, 0x63, 0x12, 0x43, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, + 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2a, 0x55, 0x0a, 0x18, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, + 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x0b, + 0x0a, 0x07, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x53, + 0x41, 0x4d, 0x45, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, + 0x04, 0x2a, 0x51, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x70, + 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, + 0x07, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4e, + 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, + 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, + 0x45, 0x44, 0x10, 0x03, 0x32, 0xe6, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x68, 0x0a, 0x02, 0x55, 0x70, 0x12, 0x30, 0x2e, 0x6e, 0x69, 0x74, 0x72, + 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x55, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x30, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, - 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x30, 0x01, 0x42, 0xbc, 0x01, 0x0a, 0x1e, 0x69, 0x6f, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, - 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x12, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x01, 0x5a, 0x48, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x74, - 0x65, 0x63, 0x68, 0x2f, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, - 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x70, 0x62, 0xaa, 0x02, 0x1b, 0x4e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x2e, 0x76, 0x31, 0xca, 0x02, 0x1b, 0x4e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x5c, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x5c, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5c, - 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x6e, 0x0a, + 0x04, 0x44, 0x6f, 0x77, 0x6e, 0x12, 0x32, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x6f, + 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x6e, 0x69, 0x74, 0x72, + 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x42, 0xbc, 0x01, + 0x0a, 0x1e, 0x69, 0x6f, 0x2e, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, + 0x42, 0x12, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x50, 0x01, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x6e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x63, 0x68, 0x2f, 0x6e, 0x69, + 0x74, 0x72, 0x69, 0x63, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, + 0x76, 0x31, 0x3b, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x70, 0x62, + 0xaa, 0x02, 0x1b, 0x4e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0xca, 0x02, + 0x1b, 0x4e, 0x69, 0x74, 0x72, 0x69, 0x63, 0x5c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5c, 0x44, 0x65, + 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5c, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2864,7 +2976,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_rawDescGZIP() []byte { } var file_nitric_proto_deployments_v1_deployments_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_nitric_proto_deployments_v1_deployments_proto_msgTypes = make([]protoimpl.MessageInfo, 35) +var file_nitric_proto_deployments_v1_deployments_proto_msgTypes = make([]protoimpl.MessageInfo, 36) var file_nitric_proto_deployments_v1_deployments_proto_goTypes = []interface{}{ (ResourceDeploymentAction)(0), // 0: nitric.proto.deployments.v1.ResourceDeploymentAction (ResourceDeploymentStatus)(0), // 1: nitric.proto.deployments.v1.ResourceDeploymentStatus @@ -2879,92 +2991,94 @@ var file_nitric_proto_deployments_v1_deployments_proto_goTypes = []interface{}{ (*Service)(nil), // 10: nitric.proto.deployments.v1.Service (*Job)(nil), // 11: nitric.proto.deployments.v1.Job (*Batch)(nil), // 12: nitric.proto.deployments.v1.Batch - (*Bucket)(nil), // 13: nitric.proto.deployments.v1.Bucket - (*BucketListener)(nil), // 14: nitric.proto.deployments.v1.BucketListener - (*Topic)(nil), // 15: nitric.proto.deployments.v1.Topic - (*Queue)(nil), // 16: nitric.proto.deployments.v1.Queue - (*KeyValueStore)(nil), // 17: nitric.proto.deployments.v1.KeyValueStore - (*Secret)(nil), // 18: nitric.proto.deployments.v1.Secret - (*SubscriptionTarget)(nil), // 19: nitric.proto.deployments.v1.SubscriptionTarget - (*TopicSubscription)(nil), // 20: nitric.proto.deployments.v1.TopicSubscription - (*HttpTarget)(nil), // 21: nitric.proto.deployments.v1.HttpTarget - (*Http)(nil), // 22: nitric.proto.deployments.v1.Http - (*Api)(nil), // 23: nitric.proto.deployments.v1.Api - (*Websocket)(nil), // 24: nitric.proto.deployments.v1.Websocket - (*WebsocketTarget)(nil), // 25: nitric.proto.deployments.v1.WebsocketTarget - (*Website)(nil), // 26: nitric.proto.deployments.v1.Website - (*ScheduleTarget)(nil), // 27: nitric.proto.deployments.v1.ScheduleTarget - (*Schedule)(nil), // 28: nitric.proto.deployments.v1.Schedule - (*SqlDatabase)(nil), // 29: nitric.proto.deployments.v1.SqlDatabase - (*ScheduleEvery)(nil), // 30: nitric.proto.deployments.v1.ScheduleEvery - (*ScheduleCron)(nil), // 31: nitric.proto.deployments.v1.ScheduleCron - (*Resource)(nil), // 32: nitric.proto.deployments.v1.Resource - (*Policy)(nil), // 33: nitric.proto.deployments.v1.Policy - (*Spec)(nil), // 34: nitric.proto.deployments.v1.Spec - nil, // 35: nitric.proto.deployments.v1.Service.EnvEntry - nil, // 36: nitric.proto.deployments.v1.Batch.EnvEntry - (*structpb.Struct)(nil), // 37: google.protobuf.Struct - (*v1.ResourceIdentifier)(nil), // 38: nitric.proto.resources.v1.ResourceIdentifier - (*v11.JobResourceRequirements)(nil), // 39: nitric.proto.batch.v1.JobResourceRequirements - (*v12.RegistrationRequest)(nil), // 40: nitric.proto.storage.v1.RegistrationRequest - (v1.Action)(0), // 41: nitric.proto.resources.v1.Action + (*BucketCorsRule)(nil), // 13: nitric.proto.deployments.v1.BucketCorsRule + (*Bucket)(nil), // 14: nitric.proto.deployments.v1.Bucket + (*BucketListener)(nil), // 15: nitric.proto.deployments.v1.BucketListener + (*Topic)(nil), // 16: nitric.proto.deployments.v1.Topic + (*Queue)(nil), // 17: nitric.proto.deployments.v1.Queue + (*KeyValueStore)(nil), // 18: nitric.proto.deployments.v1.KeyValueStore + (*Secret)(nil), // 19: nitric.proto.deployments.v1.Secret + (*SubscriptionTarget)(nil), // 20: nitric.proto.deployments.v1.SubscriptionTarget + (*TopicSubscription)(nil), // 21: nitric.proto.deployments.v1.TopicSubscription + (*HttpTarget)(nil), // 22: nitric.proto.deployments.v1.HttpTarget + (*Http)(nil), // 23: nitric.proto.deployments.v1.Http + (*Api)(nil), // 24: nitric.proto.deployments.v1.Api + (*Websocket)(nil), // 25: nitric.proto.deployments.v1.Websocket + (*WebsocketTarget)(nil), // 26: nitric.proto.deployments.v1.WebsocketTarget + (*Website)(nil), // 27: nitric.proto.deployments.v1.Website + (*ScheduleTarget)(nil), // 28: nitric.proto.deployments.v1.ScheduleTarget + (*Schedule)(nil), // 29: nitric.proto.deployments.v1.Schedule + (*SqlDatabase)(nil), // 30: nitric.proto.deployments.v1.SqlDatabase + (*ScheduleEvery)(nil), // 31: nitric.proto.deployments.v1.ScheduleEvery + (*ScheduleCron)(nil), // 32: nitric.proto.deployments.v1.ScheduleCron + (*Resource)(nil), // 33: nitric.proto.deployments.v1.Resource + (*Policy)(nil), // 34: nitric.proto.deployments.v1.Policy + (*Spec)(nil), // 35: nitric.proto.deployments.v1.Spec + nil, // 36: nitric.proto.deployments.v1.Service.EnvEntry + nil, // 37: nitric.proto.deployments.v1.Batch.EnvEntry + (*structpb.Struct)(nil), // 38: google.protobuf.Struct + (*v1.ResourceIdentifier)(nil), // 39: nitric.proto.resources.v1.ResourceIdentifier + (*v11.JobResourceRequirements)(nil), // 40: nitric.proto.batch.v1.JobResourceRequirements + (*v12.RegistrationRequest)(nil), // 41: nitric.proto.storage.v1.RegistrationRequest + (v1.Action)(0), // 42: nitric.proto.resources.v1.Action } var file_nitric_proto_deployments_v1_deployments_proto_depIdxs = []int32{ - 34, // 0: nitric.proto.deployments.v1.DeploymentUpRequest.spec:type_name -> nitric.proto.deployments.v1.Spec - 37, // 1: nitric.proto.deployments.v1.DeploymentUpRequest.attributes:type_name -> google.protobuf.Struct + 35, // 0: nitric.proto.deployments.v1.DeploymentUpRequest.spec:type_name -> nitric.proto.deployments.v1.Spec + 38, // 1: nitric.proto.deployments.v1.DeploymentUpRequest.attributes:type_name -> google.protobuf.Struct 4, // 2: nitric.proto.deployments.v1.DeploymentUpEvent.update:type_name -> nitric.proto.deployments.v1.ResourceUpdate 5, // 3: nitric.proto.deployments.v1.DeploymentUpEvent.result:type_name -> nitric.proto.deployments.v1.UpResult - 38, // 4: nitric.proto.deployments.v1.ResourceUpdate.id:type_name -> nitric.proto.resources.v1.ResourceIdentifier + 39, // 4: nitric.proto.deployments.v1.ResourceUpdate.id:type_name -> nitric.proto.resources.v1.ResourceIdentifier 0, // 5: nitric.proto.deployments.v1.ResourceUpdate.action:type_name -> nitric.proto.deployments.v1.ResourceDeploymentAction 1, // 6: nitric.proto.deployments.v1.ResourceUpdate.status:type_name -> nitric.proto.deployments.v1.ResourceDeploymentStatus - 37, // 7: nitric.proto.deployments.v1.DeploymentDownRequest.attributes:type_name -> google.protobuf.Struct + 38, // 7: nitric.proto.deployments.v1.DeploymentDownRequest.attributes:type_name -> google.protobuf.Struct 8, // 8: nitric.proto.deployments.v1.DeploymentDownEvent.result:type_name -> nitric.proto.deployments.v1.DownResult 4, // 9: nitric.proto.deployments.v1.DeploymentDownEvent.update:type_name -> nitric.proto.deployments.v1.ResourceUpdate 9, // 10: nitric.proto.deployments.v1.Service.image:type_name -> nitric.proto.deployments.v1.ImageSource - 35, // 11: nitric.proto.deployments.v1.Service.env:type_name -> nitric.proto.deployments.v1.Service.EnvEntry - 39, // 12: nitric.proto.deployments.v1.Job.requirements:type_name -> nitric.proto.batch.v1.JobResourceRequirements + 36, // 11: nitric.proto.deployments.v1.Service.env:type_name -> nitric.proto.deployments.v1.Service.EnvEntry + 40, // 12: nitric.proto.deployments.v1.Job.requirements:type_name -> nitric.proto.batch.v1.JobResourceRequirements 9, // 13: nitric.proto.deployments.v1.Batch.image:type_name -> nitric.proto.deployments.v1.ImageSource - 36, // 14: nitric.proto.deployments.v1.Batch.env:type_name -> nitric.proto.deployments.v1.Batch.EnvEntry + 37, // 14: nitric.proto.deployments.v1.Batch.env:type_name -> nitric.proto.deployments.v1.Batch.EnvEntry 11, // 15: nitric.proto.deployments.v1.Batch.jobs:type_name -> nitric.proto.deployments.v1.Job - 14, // 16: nitric.proto.deployments.v1.Bucket.listeners:type_name -> nitric.proto.deployments.v1.BucketListener - 40, // 17: nitric.proto.deployments.v1.BucketListener.config:type_name -> nitric.proto.storage.v1.RegistrationRequest - 19, // 18: nitric.proto.deployments.v1.Topic.subscriptions:type_name -> nitric.proto.deployments.v1.SubscriptionTarget - 19, // 19: nitric.proto.deployments.v1.TopicSubscription.target:type_name -> nitric.proto.deployments.v1.SubscriptionTarget - 21, // 20: nitric.proto.deployments.v1.Http.target:type_name -> nitric.proto.deployments.v1.HttpTarget - 25, // 21: nitric.proto.deployments.v1.Websocket.connect_target:type_name -> nitric.proto.deployments.v1.WebsocketTarget - 25, // 22: nitric.proto.deployments.v1.Websocket.disconnect_target:type_name -> nitric.proto.deployments.v1.WebsocketTarget - 25, // 23: nitric.proto.deployments.v1.Websocket.message_target:type_name -> nitric.proto.deployments.v1.WebsocketTarget - 27, // 24: nitric.proto.deployments.v1.Schedule.target:type_name -> nitric.proto.deployments.v1.ScheduleTarget - 30, // 25: nitric.proto.deployments.v1.Schedule.every:type_name -> nitric.proto.deployments.v1.ScheduleEvery - 31, // 26: nitric.proto.deployments.v1.Schedule.cron:type_name -> nitric.proto.deployments.v1.ScheduleCron - 38, // 27: nitric.proto.deployments.v1.Resource.id:type_name -> nitric.proto.resources.v1.ResourceIdentifier - 10, // 28: nitric.proto.deployments.v1.Resource.service:type_name -> nitric.proto.deployments.v1.Service - 13, // 29: nitric.proto.deployments.v1.Resource.bucket:type_name -> nitric.proto.deployments.v1.Bucket - 15, // 30: nitric.proto.deployments.v1.Resource.topic:type_name -> nitric.proto.deployments.v1.Topic - 23, // 31: nitric.proto.deployments.v1.Resource.api:type_name -> nitric.proto.deployments.v1.Api - 33, // 32: nitric.proto.deployments.v1.Resource.policy:type_name -> nitric.proto.deployments.v1.Policy - 28, // 33: nitric.proto.deployments.v1.Resource.schedule:type_name -> nitric.proto.deployments.v1.Schedule - 17, // 34: nitric.proto.deployments.v1.Resource.key_value_store:type_name -> nitric.proto.deployments.v1.KeyValueStore - 18, // 35: nitric.proto.deployments.v1.Resource.secret:type_name -> nitric.proto.deployments.v1.Secret - 24, // 36: nitric.proto.deployments.v1.Resource.websocket:type_name -> nitric.proto.deployments.v1.Websocket - 22, // 37: nitric.proto.deployments.v1.Resource.http:type_name -> nitric.proto.deployments.v1.Http - 16, // 38: nitric.proto.deployments.v1.Resource.queue:type_name -> nitric.proto.deployments.v1.Queue - 29, // 39: nitric.proto.deployments.v1.Resource.sql_database:type_name -> nitric.proto.deployments.v1.SqlDatabase - 12, // 40: nitric.proto.deployments.v1.Resource.batch:type_name -> nitric.proto.deployments.v1.Batch - 26, // 41: nitric.proto.deployments.v1.Resource.website:type_name -> nitric.proto.deployments.v1.Website - 32, // 42: nitric.proto.deployments.v1.Policy.principals:type_name -> nitric.proto.deployments.v1.Resource - 41, // 43: nitric.proto.deployments.v1.Policy.actions:type_name -> nitric.proto.resources.v1.Action - 32, // 44: nitric.proto.deployments.v1.Policy.resources:type_name -> nitric.proto.deployments.v1.Resource - 32, // 45: nitric.proto.deployments.v1.Spec.resources:type_name -> nitric.proto.deployments.v1.Resource - 2, // 46: nitric.proto.deployments.v1.Deployment.Up:input_type -> nitric.proto.deployments.v1.DeploymentUpRequest - 6, // 47: nitric.proto.deployments.v1.Deployment.Down:input_type -> nitric.proto.deployments.v1.DeploymentDownRequest - 3, // 48: nitric.proto.deployments.v1.Deployment.Up:output_type -> nitric.proto.deployments.v1.DeploymentUpEvent - 7, // 49: nitric.proto.deployments.v1.Deployment.Down:output_type -> nitric.proto.deployments.v1.DeploymentDownEvent - 48, // [48:50] is the sub-list for method output_type - 46, // [46:48] is the sub-list for method input_type - 46, // [46:46] is the sub-list for extension type_name - 46, // [46:46] is the sub-list for extension extendee - 0, // [0:46] is the sub-list for field type_name + 15, // 16: nitric.proto.deployments.v1.Bucket.listeners:type_name -> nitric.proto.deployments.v1.BucketListener + 13, // 17: nitric.proto.deployments.v1.Bucket.cors_rules:type_name -> nitric.proto.deployments.v1.BucketCorsRule + 41, // 18: nitric.proto.deployments.v1.BucketListener.config:type_name -> nitric.proto.storage.v1.RegistrationRequest + 20, // 19: nitric.proto.deployments.v1.Topic.subscriptions:type_name -> nitric.proto.deployments.v1.SubscriptionTarget + 20, // 20: nitric.proto.deployments.v1.TopicSubscription.target:type_name -> nitric.proto.deployments.v1.SubscriptionTarget + 22, // 21: nitric.proto.deployments.v1.Http.target:type_name -> nitric.proto.deployments.v1.HttpTarget + 26, // 22: nitric.proto.deployments.v1.Websocket.connect_target:type_name -> nitric.proto.deployments.v1.WebsocketTarget + 26, // 23: nitric.proto.deployments.v1.Websocket.disconnect_target:type_name -> nitric.proto.deployments.v1.WebsocketTarget + 26, // 24: nitric.proto.deployments.v1.Websocket.message_target:type_name -> nitric.proto.deployments.v1.WebsocketTarget + 28, // 25: nitric.proto.deployments.v1.Schedule.target:type_name -> nitric.proto.deployments.v1.ScheduleTarget + 31, // 26: nitric.proto.deployments.v1.Schedule.every:type_name -> nitric.proto.deployments.v1.ScheduleEvery + 32, // 27: nitric.proto.deployments.v1.Schedule.cron:type_name -> nitric.proto.deployments.v1.ScheduleCron + 39, // 28: nitric.proto.deployments.v1.Resource.id:type_name -> nitric.proto.resources.v1.ResourceIdentifier + 10, // 29: nitric.proto.deployments.v1.Resource.service:type_name -> nitric.proto.deployments.v1.Service + 14, // 30: nitric.proto.deployments.v1.Resource.bucket:type_name -> nitric.proto.deployments.v1.Bucket + 16, // 31: nitric.proto.deployments.v1.Resource.topic:type_name -> nitric.proto.deployments.v1.Topic + 24, // 32: nitric.proto.deployments.v1.Resource.api:type_name -> nitric.proto.deployments.v1.Api + 34, // 33: nitric.proto.deployments.v1.Resource.policy:type_name -> nitric.proto.deployments.v1.Policy + 29, // 34: nitric.proto.deployments.v1.Resource.schedule:type_name -> nitric.proto.deployments.v1.Schedule + 18, // 35: nitric.proto.deployments.v1.Resource.key_value_store:type_name -> nitric.proto.deployments.v1.KeyValueStore + 19, // 36: nitric.proto.deployments.v1.Resource.secret:type_name -> nitric.proto.deployments.v1.Secret + 25, // 37: nitric.proto.deployments.v1.Resource.websocket:type_name -> nitric.proto.deployments.v1.Websocket + 23, // 38: nitric.proto.deployments.v1.Resource.http:type_name -> nitric.proto.deployments.v1.Http + 17, // 39: nitric.proto.deployments.v1.Resource.queue:type_name -> nitric.proto.deployments.v1.Queue + 30, // 40: nitric.proto.deployments.v1.Resource.sql_database:type_name -> nitric.proto.deployments.v1.SqlDatabase + 12, // 41: nitric.proto.deployments.v1.Resource.batch:type_name -> nitric.proto.deployments.v1.Batch + 27, // 42: nitric.proto.deployments.v1.Resource.website:type_name -> nitric.proto.deployments.v1.Website + 33, // 43: nitric.proto.deployments.v1.Policy.principals:type_name -> nitric.proto.deployments.v1.Resource + 42, // 44: nitric.proto.deployments.v1.Policy.actions:type_name -> nitric.proto.resources.v1.Action + 33, // 45: nitric.proto.deployments.v1.Policy.resources:type_name -> nitric.proto.deployments.v1.Resource + 33, // 46: nitric.proto.deployments.v1.Spec.resources:type_name -> nitric.proto.deployments.v1.Resource + 2, // 47: nitric.proto.deployments.v1.Deployment.Up:input_type -> nitric.proto.deployments.v1.DeploymentUpRequest + 6, // 48: nitric.proto.deployments.v1.Deployment.Down:input_type -> nitric.proto.deployments.v1.DeploymentDownRequest + 3, // 49: nitric.proto.deployments.v1.Deployment.Up:output_type -> nitric.proto.deployments.v1.DeploymentUpEvent + 7, // 50: nitric.proto.deployments.v1.Deployment.Down:output_type -> nitric.proto.deployments.v1.DeploymentDownEvent + 49, // [49:51] is the sub-list for method output_type + 47, // [47:49] is the sub-list for method input_type + 47, // [47:47] is the sub-list for extension type_name + 47, // [47:47] is the sub-list for extension extendee + 0, // [0:47] is the sub-list for field type_name } func init() { file_nitric_proto_deployments_v1_deployments_proto_init() } @@ -3106,7 +3220,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Bucket); i { + switch v := v.(*BucketCorsRule); i { case 0: return &v.state case 1: @@ -3118,7 +3232,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BucketListener); i { + switch v := v.(*Bucket); i { case 0: return &v.state case 1: @@ -3130,7 +3244,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Topic); i { + switch v := v.(*BucketListener); i { case 0: return &v.state case 1: @@ -3142,7 +3256,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Queue); i { + switch v := v.(*Topic); i { case 0: return &v.state case 1: @@ -3154,7 +3268,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KeyValueStore); i { + switch v := v.(*Queue); i { case 0: return &v.state case 1: @@ -3166,7 +3280,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Secret); i { + switch v := v.(*KeyValueStore); i { case 0: return &v.state case 1: @@ -3178,7 +3292,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SubscriptionTarget); i { + switch v := v.(*Secret); i { case 0: return &v.state case 1: @@ -3190,7 +3304,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TopicSubscription); i { + switch v := v.(*SubscriptionTarget); i { case 0: return &v.state case 1: @@ -3202,7 +3316,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HttpTarget); i { + switch v := v.(*TopicSubscription); i { case 0: return &v.state case 1: @@ -3214,7 +3328,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Http); i { + switch v := v.(*HttpTarget); i { case 0: return &v.state case 1: @@ -3226,7 +3340,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Api); i { + switch v := v.(*Http); i { case 0: return &v.state case 1: @@ -3238,7 +3352,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Websocket); i { + switch v := v.(*Api); i { case 0: return &v.state case 1: @@ -3250,7 +3364,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WebsocketTarget); i { + switch v := v.(*Websocket); i { case 0: return &v.state case 1: @@ -3262,7 +3376,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Website); i { + switch v := v.(*WebsocketTarget); i { case 0: return &v.state case 1: @@ -3274,7 +3388,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ScheduleTarget); i { + switch v := v.(*Website); i { case 0: return &v.state case 1: @@ -3286,7 +3400,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Schedule); i { + switch v := v.(*ScheduleTarget); i { case 0: return &v.state case 1: @@ -3298,7 +3412,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SqlDatabase); i { + switch v := v.(*Schedule); i { case 0: return &v.state case 1: @@ -3310,7 +3424,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ScheduleEvery); i { + switch v := v.(*SqlDatabase); i { case 0: return &v.state case 1: @@ -3322,7 +3436,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ScheduleCron); i { + switch v := v.(*ScheduleEvery); i { case 0: return &v.state case 1: @@ -3334,7 +3448,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Resource); i { + switch v := v.(*ScheduleCron); i { case 0: return &v.state case 1: @@ -3346,7 +3460,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Policy); i { + switch v := v.(*Resource); i { case 0: return &v.state case 1: @@ -3358,6 +3472,18 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { } } file_nitric_proto_deployments_v1_deployments_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Policy); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_nitric_proto_deployments_v1_deployments_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Spec); i { case 0: return &v.state @@ -3389,35 +3515,35 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { file_nitric_proto_deployments_v1_deployments_proto_msgTypes[10].OneofWrappers = []interface{}{ (*Batch_Image)(nil), } - file_nitric_proto_deployments_v1_deployments_proto_msgTypes[12].OneofWrappers = []interface{}{ + file_nitric_proto_deployments_v1_deployments_proto_msgTypes[13].OneofWrappers = []interface{}{ (*BucketListener_Service)(nil), } - file_nitric_proto_deployments_v1_deployments_proto_msgTypes[17].OneofWrappers = []interface{}{ + file_nitric_proto_deployments_v1_deployments_proto_msgTypes[18].OneofWrappers = []interface{}{ (*SubscriptionTarget_Service)(nil), } - file_nitric_proto_deployments_v1_deployments_proto_msgTypes[19].OneofWrappers = []interface{}{ + file_nitric_proto_deployments_v1_deployments_proto_msgTypes[20].OneofWrappers = []interface{}{ (*HttpTarget_Service)(nil), } - file_nitric_proto_deployments_v1_deployments_proto_msgTypes[21].OneofWrappers = []interface{}{ + file_nitric_proto_deployments_v1_deployments_proto_msgTypes[22].OneofWrappers = []interface{}{ (*Api_Openapi)(nil), } - file_nitric_proto_deployments_v1_deployments_proto_msgTypes[23].OneofWrappers = []interface{}{ + file_nitric_proto_deployments_v1_deployments_proto_msgTypes[24].OneofWrappers = []interface{}{ (*WebsocketTarget_Service)(nil), } - file_nitric_proto_deployments_v1_deployments_proto_msgTypes[24].OneofWrappers = []interface{}{ + file_nitric_proto_deployments_v1_deployments_proto_msgTypes[25].OneofWrappers = []interface{}{ (*Website_LocalDirectory)(nil), } - file_nitric_proto_deployments_v1_deployments_proto_msgTypes[25].OneofWrappers = []interface{}{ + file_nitric_proto_deployments_v1_deployments_proto_msgTypes[26].OneofWrappers = []interface{}{ (*ScheduleTarget_Service)(nil), } - file_nitric_proto_deployments_v1_deployments_proto_msgTypes[26].OneofWrappers = []interface{}{ + file_nitric_proto_deployments_v1_deployments_proto_msgTypes[27].OneofWrappers = []interface{}{ (*Schedule_Every)(nil), (*Schedule_Cron)(nil), } - file_nitric_proto_deployments_v1_deployments_proto_msgTypes[27].OneofWrappers = []interface{}{ + file_nitric_proto_deployments_v1_deployments_proto_msgTypes[28].OneofWrappers = []interface{}{ (*SqlDatabase_ImageUri)(nil), } - file_nitric_proto_deployments_v1_deployments_proto_msgTypes[30].OneofWrappers = []interface{}{ + file_nitric_proto_deployments_v1_deployments_proto_msgTypes[31].OneofWrappers = []interface{}{ (*Resource_Service)(nil), (*Resource_Bucket)(nil), (*Resource_Topic)(nil), @@ -3439,7 +3565,7 @@ func file_nitric_proto_deployments_v1_deployments_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_nitric_proto_deployments_v1_deployments_proto_rawDesc, NumEnums: 2, - NumMessages: 35, + NumMessages: 36, NumExtensions: 0, NumServices: 1, }, diff --git a/docs/docs/providers/mappings/aws/storage.mdx b/docs/docs/providers/mappings/aws/storage.mdx index e2278b0aa..cadfa41d2 100644 --- a/docs/docs/providers/mappings/aws/storage.mdx +++ b/docs/docs/providers/mappings/aws/storage.mdx @@ -19,3 +19,4 @@ During deployment the Nitric CLI creates buckets for your stack: - Declared Buckets are created in S3 - IAM policies are created enabling your Lambda Functions to access S3 objects +- If CORS rules are configured, an [S3 CORS Configuration](https://docs.aws.amazon.com/AmazonS3/latest/userguide/cors.html) is created for the bucket diff --git a/docs/docs/providers/mappings/azure/storage.mdx b/docs/docs/providers/mappings/azure/storage.mdx index 7a211a51b..fc0fcf0e3 100644 --- a/docs/docs/providers/mappings/azure/storage.mdx +++ b/docs/docs/providers/mappings/azure/storage.mdx @@ -24,3 +24,7 @@ During deployment the Nitric CLI creates your Storage Containers: - Each Bucket declaration in your services are deployed as a Blob Container in Azure - Container Apps are configured to enable access to Storage Containers + + + Azure Blob Storage does not support per-container CORS configuration. CORS is configured at the [Storage Account level](https://learn.microsoft.com/en-us/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services). Deployments will fail if CORS rules are specified for buckets on Azure. To enable CORS, configure it directly on the Storage Account via the Azure Portal or CLI. + diff --git a/docs/docs/providers/mappings/gcp/storage.mdx b/docs/docs/providers/mappings/gcp/storage.mdx index 4dfe351d5..8d8a94ff2 100644 --- a/docs/docs/providers/mappings/gcp/storage.mdx +++ b/docs/docs/providers/mappings/gcp/storage.mdx @@ -17,3 +17,8 @@ The following resources are created when deploying Storage to Google Cloud: During deployment, your buckets will be provisioned as follows: - Your bucket definitions will be deployed individually as storage buckets. +- If CORS rules are configured, they are applied directly to the [Cloud Storage bucket CORS configuration](https://cloud.google.com/storage/docs/cross-origin). + + + GCP Cloud Storage does not support the `allowed_headers` CORS setting. GCS automatically allows all request headers when the origin and method match a CORS rule. If `allowed_headers` is specified, a warning will be emitted and the setting will be ignored. + diff --git a/docs/docs/storage.mdx b/docs/docs/storage.mdx index a96f5f056..8b6860dc4 100644 --- a/docs/docs/storage.mdx +++ b/docs/docs/storage.mdx @@ -678,6 +678,28 @@ profiles.on(BlobEventType.delete, "*", (ctx) async { +## CORS Configuration + +Cross-Origin Resource Sharing (CORS) rules can be configured on buckets to allow browser-based applications to access bucket files directly. This is useful when your frontend needs to upload or download files from a bucket using signed URLs. + +CORS rules are configured at the deployment level through the deployment spec and support the following options per rule: + +| Property | Description | +| --- | --- | +| `allowed_origins` | Origins allowed to make cross-origin requests (e.g., `https://example.com`) | +| `allowed_methods` | HTTP methods allowed (e.g., `GET`, `PUT`, `POST`) | +| `allowed_headers` | Request headers allowed in preflight requests | +| `expose_headers` | Response headers exposed to the browser | +| `max_age_seconds` | How long preflight responses can be cached (in seconds) | + + + CORS support varies by cloud provider. See the provider-specific documentation for details: + + - **AWS**: Full CORS support on S3 buckets + - **GCP**: Full CORS support on Cloud Storage buckets. `allowed_headers` is not supported — GCS automatically allows all request headers when the origin and method match. + - **Azure**: CORS is **not supported** per-bucket. Azure configures CORS at the Storage Account level, not per blob container. Deployments will fail if CORS rules are specified for Azure buckets. + + ## Cloud Service Mapping Each cloud provider comes with a set of default services used when deploying resources. You can find the default services for each cloud provider below. diff --git a/nitric/proto/deployments/v1/deployments.proto b/nitric/proto/deployments/v1/deployments.proto index fc3438e33..e3b42d5eb 100644 --- a/nitric/proto/deployments/v1/deployments.proto +++ b/nitric/proto/deployments/v1/deployments.proto @@ -190,8 +190,23 @@ message Batch { repeated Job jobs = 12; } +// CORS rule configuration for a storage bucket. +message BucketCorsRule { + // Origins allowed to make cross-origin requests (e.g., "https://example.com"). + repeated string allowed_origins = 1; + // HTTP methods allowed for cross-origin requests (e.g., "GET", "PUT"). + repeated string allowed_methods = 2; + // Request headers allowed in preflight requests. Not supported by all providers. + repeated string allowed_headers = 3; + // Response headers exposed to the browser. + repeated string expose_headers = 4; + // Maximum time in seconds a preflight response can be cached. Omit or set to 0 for provider default. + int32 max_age_seconds = 5; +} + message Bucket { repeated BucketListener listeners = 1; + repeated BucketCorsRule cors_rules = 2; } message BucketListener {