diff --git a/docs/grpc/index.html b/docs/grpc/index.html
index 3aebde5638..230b876c28 100644
--- a/docs/grpc/index.html
+++ b/docs/grpc/index.html
@@ -7441,14 +7441,16 @@
CreateActionRequest
namespace_id |
string |
|
- ID of the namespace. Required if namespace_fqn is not provided. |
+ Optional namespace ID for the custom action.
+If omitted, create targets legacy (namespace_id = NULL) behavior unless enforced by server config. |
| namespace_fqn |
string |
|
- FQN of the namespace. Required if namespace_id is not provided. |
+ Optional namespace FQN for the custom action.
+If omitted, create targets legacy (namespace_id = NULL) behavior unless enforced by server config. |
@@ -7565,14 +7567,16 @@ GetActionRequest
namespace_id |
string |
|
- ID of the namespace. Required when identifier is set to name. |
+ Optional namespace ID to scope name-based lookup.
+If omitted for name-based lookup, action search is limited to legacy (namespace_id = NULL) actions. |
| namespace_fqn |
string |
|
- FQN of the namespace. Required when identifier is set to name. |
+ Optional namespace FQN to scope name-based lookup.
+If omitted for name-based lookup, action search is limited to legacy (namespace_id = NULL) actions. |
@@ -7627,14 +7631,14 @@ ListActionsRequest
namespace_id |
string |
|
- ID of the namespace. Required if namespace_fqn is not provided. |
+ ID of the namespace to scope results. If omitted, returns actions across namespaces. |
| namespace_fqn |
string |
|
- FQN of the namespace. Required if namespace_id is not provided. |
+ FQN of the namespace to scope results. If omitted, returns actions across namespaces. |
diff --git a/docs/openapi/policy/actions/actions.openapi.yaml b/docs/openapi/policy/actions/actions.openapi.yaml
index c7189a2bfb..3ec25cd9f6 100644
--- a/docs/openapi/policy/actions/actions.openapi.yaml
+++ b/docs/openapi/policy/actions/actions.openapi.yaml
@@ -1061,13 +1061,17 @@ components:
type: string
title: namespace_id
format: uuid
- description: ID of the namespace. Required if namespace_fqn is not provided.
+ description: |-
+ Optional namespace ID for the custom action.
+ If omitted, create targets legacy (namespace_id = NULL) behavior unless enforced by server config.
namespaceFqn:
type: string
title: namespace_fqn
minLength: 1
format: uri
- description: FQN of the namespace. Required if namespace_id is not provided.
+ description: |-
+ Optional namespace FQN for the custom action.
+ If omitted, create targets legacy (namespace_id = NULL) behavior unless enforced by server config.
metadata:
title: metadata
description: Optional
@@ -1136,21 +1140,19 @@ components:
type: string
title: namespace_id
format: uuid
- description: ID of the namespace. Required when identifier is set to name.
+ description: |-
+ Optional namespace ID to scope name-based lookup.
+ If omitted for name-based lookup, action search is limited to legacy (namespace_id = NULL) actions.
namespaceFqn:
type: string
title: namespace_fqn
minLength: 1
format: uri
- description: FQN of the namespace. Required when identifier is set to name.
+ description: |-
+ Optional namespace FQN to scope name-based lookup.
+ If omitted for name-based lookup, action search is limited to legacy (namespace_id = NULL) actions.
title: GetActionRequest
additionalProperties: false
- description: |+
- Either namespace_id or namespace_fqn must be provided when getting an action by name:
- ```
- !has(this.name) || this.namespace_id != '' || this.namespace_fqn != ''
- ```
-
policy.actions.GetActionResponse:
type: object
properties:
@@ -1172,13 +1174,13 @@ components:
type: string
title: namespace_id
format: uuid
- description: ID of the namespace. Required if namespace_fqn is not provided.
+ description: ID of the namespace to scope results. If omitted, returns actions across namespaces.
namespaceFqn:
type: string
title: namespace_fqn
minLength: 1
format: uri
- description: FQN of the namespace. Required if namespace_id is not provided.
+ description: FQN of the namespace to scope results. If omitted, returns actions across namespaces.
pagination:
title: pagination
description: Optional
diff --git a/protocol/go/policy/actions/actions.pb.go b/protocol/go/policy/actions/actions.pb.go
index d6d89c407c..66e8322dce 100644
--- a/protocol/go/policy/actions/actions.pb.go
+++ b/protocol/go/policy/actions/actions.pb.go
@@ -35,9 +35,11 @@ type GetActionRequest struct {
// *GetActionRequest_Id
// *GetActionRequest_Name
Identifier isGetActionRequest_Identifier `protobuf_oneof:"identifier"`
- // ID of the namespace. Required when identifier is set to name.
+ // Optional namespace ID to scope name-based lookup.
+ // If omitted for name-based lookup, action search is limited to legacy (namespace_id = NULL) actions.
NamespaceId string `protobuf:"bytes,3,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"`
- // FQN of the namespace. Required when identifier is set to name.
+ // Optional namespace FQN to scope name-based lookup.
+ // If omitted for name-based lookup, action search is limited to legacy (namespace_id = NULL) actions.
NamespaceFqn string `protobuf:"bytes,4,opt,name=namespace_fqn,json=namespaceFqn,proto3" json:"namespace_fqn,omitempty"`
}
@@ -185,9 +187,9 @@ type ListActionsRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- // ID of the namespace. Required if namespace_fqn is not provided.
+ // ID of the namespace to scope results. If omitted, returns actions across namespaces.
NamespaceId string `protobuf:"bytes,1,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"`
- // FQN of the namespace. Required if namespace_id is not provided.
+ // FQN of the namespace to scope results. If omitted, returns actions across namespaces.
NamespaceFqn string `protobuf:"bytes,2,opt,name=namespace_fqn,json=namespaceFqn,proto3" json:"namespace_fqn,omitempty"`
// Optional
Pagination *policy.PageRequest `protobuf:"bytes,10,opt,name=pagination,proto3" json:"pagination,omitempty"`
@@ -318,9 +320,11 @@ type CreateActionRequest struct {
// Required
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
- // ID of the namespace. Required if namespace_fqn is not provided.
+ // Optional namespace ID for the custom action.
+ // If omitted, create targets legacy (namespace_id = NULL) behavior unless enforced by server config.
NamespaceId string `protobuf:"bytes,2,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"`
- // FQN of the namespace. Required if namespace_id is not provided.
+ // Optional namespace FQN for the custom action.
+ // If omitted, create targets legacy (namespace_id = NULL) behavior unless enforced by server config.
NamespaceFqn string `protobuf:"bytes,3,opt,name=namespace_fqn,json=namespaceFqn,proto3" json:"namespace_fqn,omitempty"`
// Optional
Metadata *common.MetadataMutable `protobuf:"bytes,100,opt,name=metadata,proto3" json:"metadata,omitempty"`
@@ -664,8 +668,8 @@ var file_policy_actions_actions_proto_rawDesc = []byte{
0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x1a, 0x14, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x16, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x73,
- 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x94,
- 0x05, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf5,
+ 0x03, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42,
0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12,
0xa5, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8e,
@@ -692,173 +696,163 @@ var file_policy_actions_actions_proto_rawDesc = []byte{
0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73,
0x70, 0x61, 0x63, 0x65, 0x5f, 0x66, 0x71, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d,
0xba, 0x48, 0x0a, 0xd8, 0x01, 0x01, 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x52, 0x0c, 0x6e,
- 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x46, 0x71, 0x6e, 0x3a, 0xc2, 0x01, 0xba, 0x48,
- 0xbe, 0x01, 0x1a, 0xbb, 0x01, 0x0a, 0x1b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
- 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x6e, 0x61,
- 0x6d, 0x65, 0x12, 0x54, 0x45, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73,
- 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73,
- 0x70, 0x61, 0x63, 0x65, 0x5f, 0x66, 0x71, 0x6e, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65,
- 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x67,
- 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
- 0x20, 0x62, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x46, 0x21, 0x68, 0x61, 0x73, 0x28, 0x74,
- 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69,
- 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x20, 0x21,
- 0x3d, 0x20, 0x27, 0x27, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d,
- 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x66, 0x71, 0x6e, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x27,
- 0x42, 0x13, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x05,
- 0xba, 0x48, 0x02, 0x08, 0x01, 0x22, 0x7e, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69,
- 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x61, 0x63,
- 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c,
- 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69,
- 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x10, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6d, 0x61,
- 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70,
- 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70,
- 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70,
- 0x70, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xcd, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63,
- 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x0c,
- 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0b, 0x6e, 0x61,
- 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x0d, 0x6e, 0x61, 0x6d,
- 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x66, 0x71, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
- 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x52, 0x0c, 0x6e, 0x61,
- 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x46, 0x71, 0x6e, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x61,
- 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13,
- 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a,
- 0x24, 0xba, 0x48, 0x21, 0x22, 0x1f, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
- 0x65, 0x5f, 0x69, 0x64, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f,
- 0x66, 0x71, 0x6e, 0x10, 0x01, 0x22, 0xbd, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63,
- 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a,
- 0x10, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72,
- 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79,
- 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
- 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x12, 0x35, 0x0a, 0x0e, 0x61, 0x63, 0x74, 0x69,
- 0x6f, 0x6e, 0x73, 0x5f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
- 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e,
- 0x52, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x12,
- 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67,
- 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xf7, 0x03, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
- 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xa6, 0x02,
- 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x91, 0x02, 0xba,
- 0x48, 0x8d, 0x02, 0xba, 0x01, 0x81, 0x02, 0x0a, 0x12, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
- 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xad, 0x01, 0x41, 0x63,
- 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62,
- 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69,
- 0x63, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69,
- 0x6e, 0x67, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75,
- 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e,
- 0x6f, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20,
- 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65,
- 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x61, 0x63,
- 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62,
- 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,
- 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x1a, 0x3b, 0x74, 0x68, 0x69,
- 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a,
- 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d,
- 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30,
- 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0xc8, 0x01, 0x01, 0x72, 0x03, 0x18, 0xfd, 0x01,
- 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70,
- 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48,
- 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
- 0x65, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
- 0x5f, 0x66, 0x71, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72,
- 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x52, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
- 0x65, 0x46, 0x71, 0x6e, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
- 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
- 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52,
- 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x24, 0xba, 0x48, 0x21, 0x22, 0x1f,
- 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x0a, 0x0d,
- 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x66, 0x71, 0x6e, 0x10, 0x01, 0x22,
- 0x3e, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52,
- 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f,
- 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79,
- 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22,
- 0xf3, 0x03, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69,
- 0x64, 0x12, 0xb6, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
- 0x42, 0xa1, 0x02, 0xba, 0x48, 0x9d, 0x02, 0xba, 0x01, 0x94, 0x02, 0x0a, 0x12, 0x61, 0x63, 0x74,
- 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12,
- 0xad, 0x01, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75,
- 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75,
- 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6c,
- 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x20, 0x61,
- 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x62,
- 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69,
- 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72,
- 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65,
- 0x64, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x77, 0x69,
- 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64,
- 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x1a,
- 0x4e, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30,
- 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73,
- 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f,
- 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b,
- 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x72,
- 0x03, 0x18, 0xfd, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65,
- 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63,
- 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75,
- 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12,
- 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61,
- 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, 0x01, 0x28,
- 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64,
- 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x16, 0x6d,
- 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65, 0x68,
- 0x61, 0x76, 0x69, 0x6f, 0x72, 0x22, 0x3e, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a,
- 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
- 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2f, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02,
- 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0,
- 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x3e, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
+ 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x46, 0x71, 0x6e, 0x3a, 0x24, 0xba, 0x48, 0x21,
+ 0x22, 0x1f, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64,
+ 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x66, 0x71, 0x6e, 0x10,
+ 0x00, 0x42, 0x13, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12,
+ 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x22, 0x7e, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x61,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f,
+ 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x10, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6d,
+ 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e,
+ 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61,
+ 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61,
+ 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xcd, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x41,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a,
+ 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0b, 0x6e,
+ 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x0d, 0x6e, 0x61,
+ 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x66, 0x71, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x52, 0x0c, 0x6e,
+ 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x46, 0x71, 0x6e, 0x12, 0x33, 0x0a, 0x0a, 0x70,
+ 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x13, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x3a, 0x24, 0xba, 0x48, 0x21, 0x22, 0x1f, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
+ 0x63, 0x65, 0x5f, 0x69, 0x64, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
+ 0x5f, 0x66, 0x71, 0x6e, 0x10, 0x00, 0x22, 0xbd, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x41,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39,
+ 0x0a, 0x10, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61,
+ 0x72, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63,
+ 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x12, 0x35, 0x0a, 0x0e, 0x61, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x52, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d,
+ 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61,
+ 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69,
+ 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xf7, 0x03, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74,
+ 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xa6,
+ 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x91, 0x02,
+ 0xba, 0x48, 0x8d, 0x02, 0xba, 0x01, 0x81, 0x02, 0x0a, 0x12, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xad, 0x01, 0x41,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20,
+ 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72,
+ 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77,
+ 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20,
+ 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20,
+ 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74,
+ 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74,
+ 0x65, 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x61,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20,
+ 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f,
+ 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x1a, 0x3b, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d,
+ 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41,
+ 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a,
+ 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0xc8, 0x01, 0x01, 0x72, 0x03, 0x18, 0xfd,
+ 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73,
+ 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba,
+ 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
+ 0x63, 0x65, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
+ 0x65, 0x5f, 0x66, 0x71, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07,
+ 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x52, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
+ 0x63, 0x65, 0x46, 0x71, 0x6e, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+ 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
+ 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65,
+ 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x24, 0xba, 0x48, 0x21, 0x22,
+ 0x1f, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x0a,
+ 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x66, 0x71, 0x6e, 0x10, 0x00,
+ 0x22, 0x3e, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63,
+ 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x22, 0xf3, 0x03, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02,
+ 0x69, 0x64, 0x12, 0xb6, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x42, 0xa1, 0x02, 0xba, 0x48, 0x9d, 0x02, 0xba, 0x01, 0x94, 0x02, 0x0a, 0x12, 0x61, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74,
+ 0x12, 0xad, 0x01, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d,
+ 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e,
+ 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61,
+ 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x20,
+ 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x20,
+ 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66,
+ 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61,
+ 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72,
+ 0x65, 0x64, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x77,
+ 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65,
+ 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2e,
+ 0x1a, 0x4e, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, 0x20,
+ 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65,
+ 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28,
+ 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, 0x2a,
+ 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29,
+ 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d,
+ 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d,
+ 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
+ 0x12, 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64,
+ 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61,
+ 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x16,
+ 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65,
+ 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x22, 0x3e, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26,
0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06,
- 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0xd4, 0x03, 0x0a, 0x0d, 0x41, 0x63, 0x74, 0x69, 0x6f,
- 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x52, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x41,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79,
- 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69,
- 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0b,
- 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x22, 0x2e, 0x70, 0x6f,
- 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4c, 0x69, 0x73,
- 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
- 0x23, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
- 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70,
- 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
- 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e,
- 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63,
- 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x6f,
- 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x72, 0x65,
- 0x61, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
- 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x74,
- 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x63, 0x74,
- 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f,
- 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63,
- 0x79, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
- 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
- 0x12, 0x5b, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e,
- 0x12, 0x23, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
- 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x74,
- 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xb3, 0x01,
- 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x63, 0x74,
- 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x0c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f,
- 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
- 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f,
- 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xa2, 0x02, 0x03, 0x50,
- 0x41, 0x58, 0xaa, 0x02, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69,
- 0x6f, 0x6e, 0x73, 0xca, 0x02, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x41, 0x63, 0x74,
- 0x69, 0x6f, 0x6e, 0x73, 0xe2, 0x02, 0x1a, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x41, 0x63,
- 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
- 0x61, 0xea, 0x02, 0x0f, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x41, 0x63, 0x74, 0x69,
- 0x6f, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2f, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
+ 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a,
+ 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03,
+ 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x3e, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74,
+ 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+ 0x26, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+ 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0xd4, 0x03, 0x0a, 0x0d, 0x41, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x52, 0x0a, 0x09, 0x47, 0x65, 0x74,
+ 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e,
+ 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63,
+ 0x79, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a,
+ 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x22, 0x2e, 0x70,
+ 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4c, 0x69,
+ 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x1a, 0x23, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74,
+ 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79,
+ 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70,
+ 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x72,
+ 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x6f, 0x6c, 0x69,
+ 0x63, 0x79, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
+ 0x00, 0x12, 0x5b, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x12, 0x23, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e,
+ 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xb3,
+ 0x01, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x0c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72,
+ 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f,
+ 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70,
+ 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xa2, 0x02, 0x03,
+ 0x50, 0x41, 0x58, 0xaa, 0x02, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0xca, 0x02, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x41, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xe2, 0x02, 0x1a, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x41,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
+ 0x74, 0x61, 0xea, 0x02, 0x0f, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x41, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
diff --git a/service/integration/actions_test.go b/service/integration/actions_test.go
index 456aec3fd9..31ef368af1 100644
--- a/service/integration/actions_test.go
+++ b/service/integration/actions_test.go
@@ -41,8 +41,20 @@ func (s *ActionsSuite) TearDownSuite() {
}
func (s *ActionsSuite) Test_ListActions_NoPagination_Succeeds() {
- fixtureCustomAction1 := s.f.GetCustomActionKey("custom_action_1")
- fixtureCustomAction2 := s.f.GetCustomActionKey("other_special_action")
+ name1 := fmt.Sprintf("scoped-list-nopage-1-%d", time.Now().UnixNano())
+ name2 := fmt.Sprintf("scoped-list-nopage-2-%d", time.Now().UnixNano())
+
+ created1, err := s.db.PolicyClient.CreateAction(s.ctx, &actions.CreateActionRequest{
+ Name: name1,
+ NamespaceId: s.defaultNamespaceID(),
+ })
+ s.Require().NoError(err)
+
+ created2, err := s.db.PolicyClient.CreateAction(s.ctx, &actions.CreateActionRequest{
+ Name: name2,
+ NamespaceId: s.defaultNamespaceID(),
+ })
+ s.Require().NoError(err)
list, err := s.db.PolicyClient.ListActions(s.ctx, &actions.ListActionsRequest{NamespaceId: s.defaultNamespaceID()})
s.NotNil(list)
@@ -56,10 +68,10 @@ func (s *ActionsSuite) Test_ListActions_NoPagination_Succeeds() {
foundDelete := false
for _, action := range list.GetActionsCustom() {
- switch action.GetName() {
- case fixtureCustomAction1.Name:
+ switch action.GetId() {
+ case created1.GetId():
foundCustomAction1 = true
- case fixtureCustomAction2.Name:
+ case created2.GetId():
foundCustomAction2 = true
}
}
@@ -187,28 +199,88 @@ func (s *ActionsSuite) Test_ListActions_FiltersCustomActionsByNamespace_Succeeds
s.False(foundSecond)
}
-func (s *ActionsSuite) Test_ListActions_LegacyCustomAction_NamespaceProjection_Succeeds() {
+func (s *ActionsSuite) Test_ListActions_WithoutNamespace_ReturnsAcrossNamespaces_Succeeds() {
+ name := fmt.Sprintf("global-list-action-%d", time.Now().UnixNano())
+
+ inDefault, err := s.db.PolicyClient.CreateAction(s.ctx, &actions.CreateActionRequest{
+ Name: name,
+ NamespaceId: s.defaultNamespaceID(),
+ })
+ s.Require().NoError(err)
+
+ inOther, err := s.db.PolicyClient.CreateAction(s.ctx, &actions.CreateActionRequest{
+ Name: name,
+ NamespaceId: s.otherNamespaceID(),
+ })
+ s.Require().NoError(err)
+
+ list, err := s.db.PolicyClient.ListActions(s.ctx, &actions.ListActionsRequest{})
+ s.Require().NoError(err)
+
+ foundDefault := false
+ foundOther := false
+ for _, action := range list.GetActionsCustom() {
+ if action.GetId() == inDefault.GetId() {
+ foundDefault = true
+ s.Equal(s.defaultNamespaceID(), action.GetNamespace().GetId())
+ }
+ if action.GetId() == inOther.GetId() {
+ foundOther = true
+ s.Equal(s.otherNamespaceID(), action.GetNamespace().GetId())
+ }
+ }
+
+ s.True(foundDefault)
+ s.True(foundOther)
+}
+
+func (s *ActionsSuite) Test_ListActions_LegacyCustomAction_ScopedExcluded_UnscopedIncluded_Succeeds() {
legacy := s.f.GetCustomActionKey("custom_action_1")
- assertLegacyProjected := func(list *actions.ListActionsResponse) {
+ scopedName := fmt.Sprintf("scoped-list-action-%d", time.Now().UnixNano())
+ scoped, err := s.db.PolicyClient.CreateAction(s.ctx, &actions.CreateActionRequest{
+ Name: scopedName,
+ NamespaceId: s.defaultNamespaceID(),
+ })
+ s.Require().NoError(err)
+ s.NotNil(scoped)
+
+ assertLegacyAbsent := func(list *actions.ListActionsResponse) {
s.T().Helper()
found := false
for _, action := range list.GetActionsCustom() {
if action.GetId() == legacy.ID {
found = true
- s.Equal(s.defaultNamespaceID(), action.GetNamespace().GetId())
- s.Equal(s.defaultNamespaceFQN(), action.GetNamespace().GetFqn())
}
}
- s.True(found)
+ s.False(found)
}
listByID, err := s.db.PolicyClient.ListActions(s.ctx, &actions.ListActionsRequest{NamespaceId: s.defaultNamespaceID()})
s.Require().NoError(err)
- assertLegacyProjected(listByID)
+ assertLegacyAbsent(listByID)
listByFQN, err := s.db.PolicyClient.ListActions(s.ctx, &actions.ListActionsRequest{NamespaceFqn: s.defaultNamespaceFQN()})
s.Require().NoError(err)
- assertLegacyProjected(listByFQN)
+ assertLegacyAbsent(listByFQN)
+
+ listUnscoped, err := s.db.PolicyClient.ListActions(s.ctx, &actions.ListActionsRequest{})
+ s.Require().NoError(err)
+
+ foundUnscoped := false
+ foundScoped := false
+ for _, action := range listUnscoped.GetActionsCustom() {
+ if action.GetId() == legacy.ID {
+ foundUnscoped = true
+ s.Nil(action.GetNamespace())
+ }
+ if action.GetId() == scoped.GetId() {
+ foundScoped = true
+ s.Require().NotNil(action.GetNamespace())
+ s.Equal(s.defaultNamespaceID(), action.GetNamespace().GetId())
+ }
+ }
+ s.True(foundUnscoped)
+ s.True(foundScoped)
}
func (s *ActionsSuite) Test_GetAction_Id_Succeeds() {
@@ -240,30 +312,26 @@ func (s *ActionsSuite) Test_GetAction_Id_Succeeds() {
}
func (s *ActionsSuite) Test_GetAction_Name_Succeeds() {
- customAction := s.f.GetCustomActionKey("other_special_action")
- actionCreate := s.f.GetStandardAction(policydb.ActionCreate.String())
- action, err := s.db.PolicyClient.GetAction(s.ctx, &actions.GetActionRequest{
- Identifier: &actions.GetActionRequest_Name{
- Name: customAction.Name,
- },
+ name := fmt.Sprintf("get-by-name-action-%d", time.Now().UnixNano())
+ customAction, err := s.db.PolicyClient.CreateAction(s.ctx, &actions.CreateActionRequest{
+ Name: name,
NamespaceId: s.defaultNamespaceID(),
})
- s.NotNil(action)
s.Require().NoError(err)
- s.Equal(customAction.ID, action.GetId())
- s.Equal(customAction.Name, action.GetName())
- s.NotNil(action.GetMetadata())
+ s.NotNil(customAction)
- action, err = s.db.PolicyClient.GetAction(s.ctx, &actions.GetActionRequest{
+ action, err := s.db.PolicyClient.GetAction(s.ctx, &actions.GetActionRequest{
Identifier: &actions.GetActionRequest_Name{
- Name: actionCreate.GetName(),
+ Name: customAction.GetName(),
},
NamespaceId: s.defaultNamespaceID(),
})
s.NotNil(action)
s.Require().NoError(err)
- s.Equal(actionCreate.GetName(), action.GetName())
- s.Equal(actionCreate.GetId(), action.GetId())
+ s.Equal(customAction.GetId(), action.GetId())
+ s.Equal(customAction.GetName(), action.GetName())
+ s.Require().NotNil(action.GetNamespace())
+ s.Equal(s.defaultNamespaceID(), action.GetNamespace().GetId())
s.NotNil(action.GetMetadata())
}
@@ -299,28 +367,47 @@ func (s *ActionsSuite) Test_GetAction_Name_ResolvesByNamespace_Succeeds() {
s.Equal(s.otherNamespaceID(), gotOther.GetNamespace().GetId())
}
-func (s *ActionsSuite) Test_GetAction_Name_LegacyCustomAction_Succeeds() {
+func (s *ActionsSuite) Test_GetAction_Name_LegacyCustomAction_UnscopedSucceeds_ScopedFails() {
legacy := s.f.GetCustomActionKey("other_special_action")
- assertLegacyGet := func(action *policy.Action) {
+
+ byUnscoped, err := s.db.PolicyClient.GetAction(s.ctx, &actions.GetActionRequest{
+ Identifier: &actions.GetActionRequest_Name{Name: legacy.Name},
+ })
+ s.Require().NoError(err)
+ s.NotNil(byUnscoped)
+ s.Equal(legacy.ID, byUnscoped.GetId())
+ s.Nil(byUnscoped.GetNamespace())
+
+ assertLegacyGet := func(action *policy.Action, err error) {
s.T().Helper()
- s.Equal(legacy.ID, action.GetId())
- s.Equal(s.defaultNamespaceID(), action.GetNamespace().GetId())
- s.Equal(s.defaultNamespaceFQN(), action.GetNamespace().GetFqn())
+ s.Nil(action)
+ s.Require().Error(err)
+ s.Require().ErrorIs(err, db.ErrNotFound)
}
byID, err := s.db.PolicyClient.GetAction(s.ctx, &actions.GetActionRequest{
Identifier: &actions.GetActionRequest_Name{Name: legacy.Name},
NamespaceId: s.defaultNamespaceID(),
})
- s.Require().NoError(err)
- assertLegacyGet(byID)
+ assertLegacyGet(byID, err)
byFQN, err := s.db.PolicyClient.GetAction(s.ctx, &actions.GetActionRequest{
Identifier: &actions.GetActionRequest_Name{Name: legacy.Name},
NamespaceFqn: s.defaultNamespaceFQN(),
})
- s.Require().NoError(err)
- assertLegacyGet(byFQN)
+ assertLegacyGet(byFQN, err)
+
+ byOtherID, err := s.db.PolicyClient.GetAction(s.ctx, &actions.GetActionRequest{
+ Identifier: &actions.GetActionRequest_Name{Name: legacy.Name},
+ NamespaceId: s.otherNamespaceID(),
+ })
+ assertLegacyGet(byOtherID, err)
+
+ byOtherFQN, err := s.db.PolicyClient.GetAction(s.ctx, &actions.GetActionRequest{
+ Identifier: &actions.GetActionRequest_Name{Name: legacy.Name},
+ NamespaceFqn: s.otherNamespaceFQN(),
+ })
+ assertLegacyGet(byOtherFQN, err)
}
func (s *ActionsSuite) Test_CreateListGetAction_WithNamespaceFQN_Succeeds() {
@@ -417,6 +504,15 @@ func (s *ActionsSuite) Test_CreateAction_Conflict_Fails() {
s.Require().ErrorIs(err, db.ErrUniqueConstraintViolation)
}
+func (s *ActionsSuite) Test_CreateAction_MissingNamespace_SucceedsInLegacyMode() {
+ action, err := s.db.PolicyClient.CreateAction(s.ctx, &actions.CreateActionRequest{
+ Name: fmt.Sprintf("missing-namespace-%d", time.Now().UnixNano()),
+ })
+ s.Require().NoError(err)
+ s.NotNil(action)
+ s.Nil(action.GetNamespace())
+}
+
func (s *ActionsSuite) Test_CreateAction_NormalizesToLowerCase() {
newName := "New_Custom_Action_CreateAction_UPPER"
action, err := s.db.PolicyClient.CreateAction(s.ctx, &actions.CreateActionRequest{
diff --git a/service/integration/registered_resources_test.go b/service/integration/registered_resources_test.go
index 1067bb6aa8..afba4e8d71 100644
--- a/service/integration/registered_resources_test.go
+++ b/service/integration/registered_resources_test.go
@@ -1939,45 +1939,6 @@ func (s *RegisteredResourcesSuite) Test_SameNamespaceEnforcement_SameNamespace_S
s.Require().Len(resVal.GetActionAttributeValues(), 1)
}
-func (s *RegisteredResourcesSuite) Test_CreateRegisteredResourceValue_WithNamespacedCustomActionName_Succeeds() {
- nsID := s.getNamespaceID("example.com")
-
- res, err := s.db.PolicyClient.CreateRegisteredResource(s.ctx, ®isteredresources.CreateRegisteredResourceRequest{
- NamespaceId: nsID,
- Name: fmt.Sprintf("test_rr_custom_action_name_%d", time.Now().UnixNano()),
- })
- s.Require().NoError(err)
- s.NotNil(res)
-
- customActionName := fmt.Sprintf("rr_custom_action_%d", time.Now().UnixNano())
- customAction, err := s.db.PolicyClient.CreateAction(s.ctx, &pbActions.CreateActionRequest{
- Name: customActionName,
- NamespaceId: nsID,
- })
- s.Require().NoError(err)
- s.NotNil(customAction)
-
- resVal, err := s.db.PolicyClient.CreateRegisteredResourceValue(s.ctx, ®isteredresources.CreateRegisteredResourceValueRequest{
- ResourceId: res.GetId(),
- Value: fmt.Sprintf("test_rr_custom_action_name_value_%d", time.Now().UnixNano()),
- ActionAttributeValues: []*registeredresources.ActionAttributeValue{
- {
- ActionIdentifier: ®isteredresources.ActionAttributeValue_ActionName{
- ActionName: customActionName,
- },
- AttributeValueIdentifier: ®isteredresources.ActionAttributeValue_AttributeValueFqn{
- AttributeValueFqn: "https://example.com/attr/attr1/value/value1",
- },
- },
- },
- })
- s.Require().NoError(err)
- s.NotNil(resVal)
- s.Require().Len(resVal.GetActionAttributeValues(), 1)
- s.Equal(customAction.GetId(), resVal.GetActionAttributeValues()[0].GetAction().GetId())
- s.Equal(customActionName, resVal.GetActionAttributeValues()[0].GetAction().GetName())
-}
-
func (s *RegisteredResourcesSuite) getNamespaceID(key string) string {
ns := s.f.GetNamespaceKey(key)
return ns.ID
diff --git a/service/policy/actions/actions.go b/service/policy/actions/actions.go
index fe263f1030..6c4f5ca5e9 100644
--- a/service/policy/actions/actions.go
+++ b/service/policy/actions/actions.go
@@ -2,6 +2,7 @@ package actions
import (
"context"
+ "errors"
"fmt"
"log/slog"
@@ -112,6 +113,10 @@ func (a *ActionService) ListActions(ctx context.Context, req *connect.Request[ac
func (a *ActionService) CreateAction(ctx context.Context, req *connect.Request[actions.CreateActionRequest]) (*connect.Response[actions.CreateActionResponse], error) {
a.logger.DebugContext(ctx, "creating action", slog.String("name", req.Msg.GetName()))
+ if a.config.NamespacedPolicy && req.Msg.GetNamespaceId() == "" && req.Msg.GetNamespaceFqn() == "" {
+ return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("either namespace_id or namespace_fqn must be provided"))
+ }
+
auditParams := audit.PolicyEventParams{
ActionType: audit.ActionTypeCreate,
ObjectType: audit.ObjectTypeAction,
diff --git a/service/policy/actions/actions.proto b/service/policy/actions/actions.proto
index 7ae91a9b6a..7065e2d503 100644
--- a/service/policy/actions/actions.proto
+++ b/service/policy/actions/actions.proto
@@ -12,11 +12,7 @@ import "policy/selectors.proto";
*/
message GetActionRequest {
- option (buf.validate.message).cel = {
- id: "namespace_required_for_name"
- message: "Either namespace_id or namespace_fqn must be provided when getting an action by name"
- expression: "!has(this.name) || this.namespace_id != '' || this.namespace_fqn != ''"
- };
+ option (buf.validate.message).oneof = { fields: ["namespace_id", "namespace_fqn"], required: false };
// Required
oneof identifier {
@@ -32,12 +28,14 @@ message GetActionRequest {
];
}
- // ID of the namespace. Required when identifier is set to name.
+ // Optional namespace ID to scope name-based lookup.
+ // If omitted for name-based lookup, action search is limited to legacy (namespace_id = NULL) actions.
string namespace_id = 3 [
(buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE,
(buf.validate.field).string.uuid = true
];
- // FQN of the namespace. Required when identifier is set to name.
+ // Optional namespace FQN to scope name-based lookup.
+ // If omitted for name-based lookup, action search is limited to legacy (namespace_id = NULL) actions.
string namespace_fqn = 4 [
(buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE,
(buf.validate.field).string = {
@@ -54,12 +52,14 @@ message GetActionResponse {
}
message ListActionsRequest {
- // Required
- option (buf.validate.message).oneof = { fields: ["namespace_id", "namespace_fqn"], required: true };
+ // Optional
+ option (buf.validate.message).oneof = { fields: ["namespace_id", "namespace_fqn"], required: false };
- // ID of the namespace. Required if namespace_fqn is not provided.
- string namespace_id = 1 [(buf.validate.field).string.uuid = true];
- // FQN of the namespace. Required if namespace_id is not provided.
+ // ID of the namespace to scope results. If omitted, returns actions across namespaces.
+ string namespace_id = 1 [
+ (buf.validate.field).string.uuid = true
+ ];
+ // FQN of the namespace to scope results. If omitted, returns actions across namespaces.
string namespace_fqn = 2 [
(buf.validate.field).string = {
min_len : 1
@@ -80,8 +80,8 @@ message ListActionsResponse {
// Create a new Custom action name with optional metadata.
// Creation of Standard actions is not supported.
message CreateActionRequest {
- // Required
- option (buf.validate.message).oneof = { fields: ["namespace_id", "namespace_fqn"], required: true };
+ // Optional
+ option (buf.validate.message).oneof = { fields: ["namespace_id", "namespace_fqn"], required: false };
// Required
string name = 1 [
@@ -94,9 +94,11 @@ message CreateActionRequest {
}
];
- // ID of the namespace. Required if namespace_fqn is not provided.
+ // Optional namespace ID for the custom action.
+ // If omitted, create targets legacy (namespace_id = NULL) behavior unless enforced by server config.
string namespace_id = 2 [(buf.validate.field).string.uuid = true];
- // FQN of the namespace. Required if namespace_id is not provided.
+ // Optional namespace FQN for the custom action.
+ // If omitted, create targets legacy (namespace_id = NULL) behavior unless enforced by server config.
string namespace_fqn = 3 [
(buf.validate.field).string = {
min_len : 1
diff --git a/service/policy/actions/actions_test.go b/service/policy/actions/actions_test.go
index 354321b5f1..fd5daf39ef 100644
--- a/service/policy/actions/actions_test.go
+++ b/service/policy/actions/actions_test.go
@@ -19,8 +19,6 @@ const (
errMessageActionNameFormat = "action_name_format"
errMessageURI = "string.uri"
errMessageRequired = "required"
- errMessageOneof = "message.oneof"
- errMessageNamespaceByName = "namespace_required_for_name"
)
var (
@@ -91,14 +89,6 @@ func (s *ActionSuite) Test_CreateActionRequest_Fails() {
s.Require().Error(err)
s.Require().Contains(err.Error(), errMessageMaxLength)
- // namespace required
- req = &actions.CreateActionRequest{
- Name: "valid_name",
- }
- err = s.v.Validate(req)
- s.Require().Error(err)
- s.Require().Contains(err.Error(), errMessageOneof)
-
// invalid namespace id
req = &actions.CreateActionRequest{
Name: "valid_name",
@@ -130,15 +120,22 @@ func (s *ActionSuite) Test_CreateActionRequest_Succeeds() {
})
}
- // with metadata
+ // with no namespace
req := &actions.CreateActionRequest{
+ Name: "valid_name",
+ }
+ err := s.v.Validate(req)
+ s.Require().NoError(err)
+
+ // with metadata
+ req = &actions.CreateActionRequest{
Name: "valid_name",
NamespaceId: validUUID,
Metadata: &common.MetadataMutable{
Labels: map[string]string{"key": "value"},
},
}
- err := s.v.Validate(req)
+ err = s.v.Validate(req)
s.Require().NoError(err)
}
@@ -157,7 +154,6 @@ func (s *ActionSuite) Test_GetAction_Succeeds() {
Identifier: &actions.GetActionRequest_Name{
Name: name,
},
- NamespaceFqn: validNamespaceFQN,
}
err := s.v.Validate(req)
s.Require().NoError(err)
@@ -181,16 +177,6 @@ func (s *ActionSuite) Test_GetAction_Fails() {
s.Require().Error(err)
s.Require().Contains(err.Error(), errMessageRequired)
- // missing namespace
- req = &actions.GetActionRequest{
- Identifier: &actions.GetActionRequest_Name{
- Name: "valid_name",
- },
- }
- err = s.v.Validate(req)
- s.Require().Error(err)
- s.Require().Contains(err.Error(), errMessageNamespaceByName)
-
for _, name := range actionNamesInvalidFormat {
s.Run(name, func() {
req = &actions.GetActionRequest{
@@ -240,13 +226,17 @@ func (s *ActionSuite) Test_GetAction_Fails() {
}
func (s *ActionSuite) Test_ListActions_Succeeds() {
+ reqNoNamespace := &actions.ListActionsRequest{}
+ err := s.v.Validate(reqNoNamespace)
+ s.Require().NoError(err)
+
reqPaginated := &actions.ListActionsRequest{
NamespaceId: validUUID,
Pagination: &policy.PageRequest{
Limit: 1,
},
}
- err := s.v.Validate(reqPaginated)
+ err = s.v.Validate(reqPaginated)
s.Require().NoError(err)
reqPaginated.Pagination.Offset = 100
@@ -259,15 +249,9 @@ func (s *ActionSuite) Test_ListActions_Succeeds() {
}
func (s *ActionSuite) Test_ListActions_Fails() {
- // missing namespace
- req := &actions.ListActionsRequest{}
- err := s.v.Validate(req)
- s.Require().Error(err)
- s.Require().Contains(err.Error(), errMessageOneof)
-
// invalid namespace id
- req = &actions.ListActionsRequest{NamespaceId: "invalid-uuid"}
- err = s.v.Validate(req)
+ req := &actions.ListActionsRequest{NamespaceId: "invalid-uuid"}
+ err := s.v.Validate(req)
s.Require().Error(err)
s.Require().Contains(err.Error(), errMessageUUID)
diff --git a/service/policy/config/config.go b/service/policy/config/config.go
index 0f7a74dace..d237001aa7 100644
--- a/service/policy/config/config.go
+++ b/service/policy/config/config.go
@@ -15,6 +15,8 @@ type Config struct {
ListRequestLimitDefault int `mapstructure:"list_request_limit_default" default:"1000"`
// Maximum pagination list limit allowed by policy services
ListRequestLimitMax int `mapstructure:"list_request_limit_max" default:"2500"`
+ // Enable support for namespaced policies. If false, namespace fields are ignored and treated as null.
+ NamespacedPolicy bool `mapstructure:"namespaced_policy" default:"false"`
}
func (c Config) Validate() error {
diff --git a/service/policy/db/actions.go b/service/policy/db/actions.go
index adef373dfa..fc212dd126 100644
--- a/service/policy/db/actions.go
+++ b/service/policy/db/actions.go
@@ -150,6 +150,7 @@ func (c PolicyDBClient) CreateAction(ctx context.Context, req *actions.CreateAct
}
namespaceID := req.GetNamespaceId()
+ namespaceFQN := req.GetNamespaceFqn()
useID := len(namespaceID) > 0
parsedID := pgtypeUUID(namespaceID)
if useID && !parsedID.Valid {
@@ -164,7 +165,7 @@ func (c PolicyDBClient) CreateAction(ctx context.Context, req *actions.CreateAct
Name: name,
Metadata: metadataJSON,
NamespaceID: parsedID,
- NamespaceFqn: pgtypeText(req.GetNamespaceFqn()),
+ NamespaceFqn: pgtypeText(namespaceFQN),
}
createdID, err := c.queries.createCustomAction(ctx, createParams)
diff --git a/service/policy/db/actions.sql.go b/service/policy/db/actions.sql.go
index 9972a65314..e9fc2875c2 100644
--- a/service/policy/db/actions.sql.go
+++ b/service/policy/db/actions.sql.go
@@ -26,6 +26,8 @@ SELECT
FROM ns
LEFT JOIN attribute_fqns fqns ON fqns.fqn = ns.fqn AND ns.id IS NULL
WHERE
+ (ns.id IS NULL AND ns.fqn IS NULL)
+ OR
(ns.id IS NOT NULL)
OR
(ns.fqn IS NOT NULL AND fqns.namespace_id IS NOT NULL)
@@ -55,6 +57,8 @@ type createCustomActionParams struct {
// FROM ns
// LEFT JOIN attribute_fqns fqns ON fqns.fqn = ns.fqn AND ns.id IS NULL
// WHERE
+// (ns.id IS NULL AND ns.fqn IS NULL)
+// OR
// (ns.id IS NOT NULL)
// OR
// (ns.fqn IS NOT NULL AND fqns.namespace_id IS NOT NULL)
@@ -227,11 +231,6 @@ SELECT
a.is_standard,
JSON_STRIP_NULLS(JSON_BUILD_OBJECT('labels', a.metadata -> 'labels', 'created_at', a.created_at, 'updated_at', a.updated_at)) AS metadata,
CASE
- WHEN a.namespace_id IS NULL AND $1::text IS NOT NULL THEN JSON_BUILD_OBJECT(
- 'id', rn.id,
- 'name', rn.name,
- 'fqn', rn.fqn
- )
WHEN a.namespace_id IS NULL THEN NULL
ELSE JSON_BUILD_OBJECT(
'id', n.id,
@@ -245,13 +244,13 @@ LEFT JOIN attribute_fqns ns_fqns ON ns_fqns.namespace_id = n.id AND ns_fqns.attr
LEFT JOIN resolved_namespace rn ON TRUE
WHERE
(
- ($2::uuid IS NOT NULL AND a.id = $2::uuid)
+ ($1::uuid IS NOT NULL AND a.id = $1::uuid)
OR
(
- $1::text IS NOT NULL
- AND a.name = $1::text
+ $2::text IS NOT NULL
+ AND a.name = $2::text
AND (
- (rn.id IS NOT NULL AND (a.namespace_id = rn.id OR a.namespace_id IS NULL))
+ (rn.id IS NOT NULL AND a.namespace_id = rn.id)
OR
(rn.id IS NULL AND a.namespace_id IS NULL)
)
@@ -268,8 +267,8 @@ LIMIT 1
`
type getActionParams struct {
- Name pgtype.Text `json:"name"`
ID pgtype.UUID `json:"id"`
+ Name pgtype.Text `json:"name"`
NamespaceID pgtype.UUID `json:"namespace_id"`
NamespaceFqn pgtype.Text `json:"namespace_fqn"`
}
@@ -303,11 +302,6 @@ type getActionRow struct {
// a.is_standard,
// JSON_STRIP_NULLS(JSON_BUILD_OBJECT('labels', a.metadata -> 'labels', 'created_at', a.created_at, 'updated_at', a.updated_at)) AS metadata,
// CASE
-// WHEN a.namespace_id IS NULL AND $1::text IS NOT NULL THEN JSON_BUILD_OBJECT(
-// 'id', rn.id,
-// 'name', rn.name,
-// 'fqn', rn.fqn
-// )
// WHEN a.namespace_id IS NULL THEN NULL
// ELSE JSON_BUILD_OBJECT(
// 'id', n.id,
@@ -321,13 +315,13 @@ type getActionRow struct {
// LEFT JOIN resolved_namespace rn ON TRUE
// WHERE
// (
-// ($2::uuid IS NOT NULL AND a.id = $2::uuid)
+// ($1::uuid IS NOT NULL AND a.id = $1::uuid)
// OR
// (
-// $1::text IS NOT NULL
-// AND a.name = $1::text
+// $2::text IS NOT NULL
+// AND a.name = $2::text
// AND (
-// (rn.id IS NOT NULL AND (a.namespace_id = rn.id OR a.namespace_id IS NULL))
+// (rn.id IS NOT NULL AND a.namespace_id = rn.id)
// OR
// (rn.id IS NULL AND a.namespace_id IS NULL)
// )
@@ -343,8 +337,8 @@ type getActionRow struct {
// LIMIT 1
func (q *Queries) getAction(ctx context.Context, arg getActionParams) (getActionRow, error) {
row := q.db.QueryRow(ctx, getAction,
- arg.Name,
arg.ID,
+ arg.Name,
arg.NamespaceID,
arg.NamespaceFqn,
)
@@ -369,16 +363,10 @@ WITH resolved_namespace AS (
FROM attribute_namespaces n
LEFT JOIN attribute_fqns fqns ON fqns.namespace_id = n.id AND fqns.attribute_id IS NULL AND fqns.value_id IS NULL
WHERE
- ($3::uuid IS NOT NULL AND n.id = $3::uuid)
+ ($1::uuid IS NOT NULL AND n.id = $1::uuid)
OR
- ($4::text IS NOT NULL AND fqns.fqn = $4::text)
+ ($2::text IS NOT NULL AND fqns.fqn = $2::text)
LIMIT 1
-),
-counted AS (
- SELECT COUNT(a.id) AS total
- FROM actions a
- JOIN resolved_namespace rn ON TRUE
- WHERE a.is_standard = TRUE OR a.namespace_id = rn.id OR a.namespace_id IS NULL
)
SELECT
a.id,
@@ -390,34 +378,35 @@ SELECT
)) as metadata,
a.is_standard,
CASE
- WHEN a.namespace_id IS NULL THEN JSON_BUILD_OBJECT(
- 'id', rn.id,
- 'name', rn.name,
- 'fqn', rn.fqn
- )
+ WHEN a.namespace_id IS NULL THEN NULL
ELSE JSON_BUILD_OBJECT(
'id', n.id,
'name', n.name,
'fqn', ns_fqns.fqn
)
END AS namespace,
- counted.total
+ COUNT(*) OVER() as total
FROM actions a
-JOIN resolved_namespace rn ON TRUE
+LEFT JOIN resolved_namespace rn ON TRUE
LEFT JOIN attribute_namespaces n ON a.namespace_id = n.id
LEFT JOIN attribute_fqns ns_fqns ON ns_fqns.namespace_id = n.id AND ns_fqns.attribute_id IS NULL AND ns_fqns.value_id IS NULL
-CROSS JOIN counted
-WHERE a.is_standard = TRUE OR a.namespace_id = rn.id OR a.namespace_id IS NULL
+WHERE
+ (
+ $1::uuid IS NULL
+ AND $2::text IS NULL
+ )
+ OR a.is_standard = TRUE
+ OR a.namespace_id = rn.id
ORDER BY a.created_at DESC
-LIMIT $2
-OFFSET $1
+LIMIT $4
+OFFSET $3
`
type listActionsParams struct {
- Offset int32 `json:"offset_"`
- Limit int32 `json:"limit_"`
NamespaceID pgtype.UUID `json:"namespace_id"`
NamespaceFqn pgtype.Text `json:"namespace_fqn"`
+ Offset int32 `json:"offset_"`
+ Limit int32 `json:"limit_"`
}
type listActionsRow struct {
@@ -441,16 +430,10 @@ type listActionsRow struct {
// FROM attribute_namespaces n
// LEFT JOIN attribute_fqns fqns ON fqns.namespace_id = n.id AND fqns.attribute_id IS NULL AND fqns.value_id IS NULL
// WHERE
-// ($3::uuid IS NOT NULL AND n.id = $3::uuid)
+// ($1::uuid IS NOT NULL AND n.id = $1::uuid)
// OR
-// ($4::text IS NOT NULL AND fqns.fqn = $4::text)
+// ($2::text IS NOT NULL AND fqns.fqn = $2::text)
// LIMIT 1
-// ),
-// counted AS (
-// SELECT COUNT(a.id) AS total
-// FROM actions a
-// JOIN resolved_namespace rn ON TRUE
-// WHERE a.is_standard = TRUE OR a.namespace_id = rn.id OR a.namespace_id IS NULL
// )
// SELECT
// a.id,
@@ -462,33 +445,34 @@ type listActionsRow struct {
// )) as metadata,
// a.is_standard,
// CASE
-// WHEN a.namespace_id IS NULL THEN JSON_BUILD_OBJECT(
-// 'id', rn.id,
-// 'name', rn.name,
-// 'fqn', rn.fqn
-// )
+// WHEN a.namespace_id IS NULL THEN NULL
// ELSE JSON_BUILD_OBJECT(
// 'id', n.id,
// 'name', n.name,
// 'fqn', ns_fqns.fqn
// )
// END AS namespace,
-// counted.total
+// COUNT(*) OVER() as total
// FROM actions a
-// JOIN resolved_namespace rn ON TRUE
+// LEFT JOIN resolved_namespace rn ON TRUE
// LEFT JOIN attribute_namespaces n ON a.namespace_id = n.id
// LEFT JOIN attribute_fqns ns_fqns ON ns_fqns.namespace_id = n.id AND ns_fqns.attribute_id IS NULL AND ns_fqns.value_id IS NULL
-// CROSS JOIN counted
-// WHERE a.is_standard = TRUE OR a.namespace_id = rn.id OR a.namespace_id IS NULL
+// WHERE
+// (
+// $1::uuid IS NULL
+// AND $2::text IS NULL
+// )
+// OR a.is_standard = TRUE
+// OR a.namespace_id = rn.id
// ORDER BY a.created_at DESC
-// LIMIT $2
-// OFFSET $1
+// LIMIT $4
+// OFFSET $3
func (q *Queries) listActions(ctx context.Context, arg listActionsParams) ([]listActionsRow, error) {
rows, err := q.db.Query(ctx, listActions,
- arg.Offset,
- arg.Limit,
arg.NamespaceID,
arg.NamespaceFqn,
+ arg.Offset,
+ arg.Limit,
)
if err != nil {
return nil, err
diff --git a/service/policy/db/queries/actions.sql b/service/policy/db/queries/actions.sql
index 7d4744cf20..718f5342b9 100644
--- a/service/policy/db/queries/actions.sql
+++ b/service/policy/db/queries/actions.sql
@@ -15,12 +15,6 @@ WITH resolved_namespace AS (
OR
(sqlc.narg('namespace_fqn')::text IS NOT NULL AND fqns.fqn = sqlc.narg('namespace_fqn')::text)
LIMIT 1
-),
-counted AS (
- SELECT COUNT(a.id) AS total
- FROM actions a
- JOIN resolved_namespace rn ON TRUE
- WHERE a.is_standard = TRUE OR a.namespace_id = rn.id OR a.namespace_id IS NULL
)
SELECT
a.id,
@@ -32,24 +26,25 @@ SELECT
)) as metadata,
a.is_standard,
CASE
- WHEN a.namespace_id IS NULL THEN JSON_BUILD_OBJECT(
- 'id', rn.id,
- 'name', rn.name,
- 'fqn', rn.fqn
- )
+ WHEN a.namespace_id IS NULL THEN NULL
ELSE JSON_BUILD_OBJECT(
'id', n.id,
'name', n.name,
'fqn', ns_fqns.fqn
)
END AS namespace,
- counted.total
+ COUNT(*) OVER() as total
FROM actions a
-JOIN resolved_namespace rn ON TRUE
+LEFT JOIN resolved_namespace rn ON TRUE
LEFT JOIN attribute_namespaces n ON a.namespace_id = n.id
LEFT JOIN attribute_fqns ns_fqns ON ns_fqns.namespace_id = n.id AND ns_fqns.attribute_id IS NULL AND ns_fqns.value_id IS NULL
-CROSS JOIN counted
-WHERE a.is_standard = TRUE OR a.namespace_id = rn.id OR a.namespace_id IS NULL
+WHERE
+ (
+ sqlc.narg('namespace_id')::uuid IS NULL
+ AND sqlc.narg('namespace_fqn')::text IS NULL
+ )
+ OR a.is_standard = TRUE
+ OR a.namespace_id = rn.id
ORDER BY a.created_at DESC
LIMIT @limit_
OFFSET @offset_;
@@ -74,11 +69,6 @@ SELECT
a.is_standard,
JSON_STRIP_NULLS(JSON_BUILD_OBJECT('labels', a.metadata -> 'labels', 'created_at', a.created_at, 'updated_at', a.updated_at)) AS metadata,
CASE
- WHEN a.namespace_id IS NULL AND sqlc.narg('name')::text IS NOT NULL THEN JSON_BUILD_OBJECT(
- 'id', rn.id,
- 'name', rn.name,
- 'fqn', rn.fqn
- )
WHEN a.namespace_id IS NULL THEN NULL
ELSE JSON_BUILD_OBJECT(
'id', n.id,
@@ -98,7 +88,7 @@ WHERE
sqlc.narg('name')::text IS NOT NULL
AND a.name = sqlc.narg('name')::text
AND (
- (rn.id IS NOT NULL AND (a.namespace_id = rn.id OR a.namespace_id IS NULL))
+ (rn.id IS NOT NULL AND a.namespace_id = rn.id)
OR
(rn.id IS NULL AND a.namespace_id IS NULL)
)
@@ -169,6 +159,8 @@ SELECT
FROM ns
LEFT JOIN attribute_fqns fqns ON fqns.fqn = ns.fqn AND ns.id IS NULL
WHERE
+ (ns.id IS NULL AND ns.fqn IS NULL)
+ OR
(ns.id IS NOT NULL)
OR
(ns.fqn IS NOT NULL AND fqns.namespace_id IS NOT NULL)
diff --git a/service/policy/db/registered_resources.go b/service/policy/db/registered_resources.go
index a14a7965d9..61d3109d54 100644
--- a/service/policy/db/registered_resources.go
+++ b/service/policy/db/registered_resources.go
@@ -585,8 +585,7 @@ func (c PolicyDBClient) createRegisteredResourceActionAttributeValues(ctx contex
actionID = ident.ActionId
case *registeredresources.ActionAttributeValue_ActionName:
a, err := c.queries.getAction(ctx, getActionParams{
- Name: pgtypeText(strings.ToLower(ident.ActionName)),
- NamespaceID: pgtypeUUID(resourceNamespaceID),
+ Name: pgtypeText(strings.ToLower(ident.ActionName)),
})
if err != nil {
return db.WrapIfKnownInvalidQueryErr(err)