diff --git a/aggregator/rpc_server.go b/aggregator/rpc_server.go index 8d34b336..8fbe25e3 100644 --- a/aggregator/rpc_server.go +++ b/aggregator/rpc_server.go @@ -248,6 +248,77 @@ func (r *RpcServer) TriggerTask(ctx context.Context, payload *avsproto.UserTrigg return r.engine.TriggerTask(user, payload) } +func (r *RpcServer) CreateSecret(ctx context.Context, payload *avsproto.CreateOrUpdateSecretReq) (*wrapperspb.BoolValue, error) { + user, err := r.verifyAuth(ctx) + if err != nil { + return nil, status.Errorf(codes.Unauthenticated, "%s: %s", auth.AuthenticationError, err.Error()) + } + + r.config.Logger.Info("process create secret", + "user", user.Address.String(), + "secret_name", payload.Name, + ) + + result, err := r.engine.CreateSecret(user, payload) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "") + } + + return wrapperspb.Bool(result), nil +} + +func (r *RpcServer) ListSecrets(ctx context.Context, payload *avsproto.ListSecretsReq) (*avsproto.ListSecretsResp, error) { + user, err := r.verifyAuth(ctx) + if err != nil { + return nil, status.Errorf(codes.Unauthenticated, "%s: %s", auth.AuthenticationError, err.Error()) + } + + r.config.Logger.Info("process list secret", + "user", user.Address.String(), + ) + + return r.engine.ListSecrets(user, payload) +} + +func (r *RpcServer) UpdateSecret(ctx context.Context, payload *avsproto.CreateOrUpdateSecretReq) (*wrapperspb.BoolValue, error) { + user, err := r.verifyAuth(ctx) + if err != nil { + return nil, status.Errorf(codes.Unauthenticated, "%s: %s", auth.AuthenticationError, err.Error()) + } + + r.config.Logger.Info("process update secret", + "user", user.Address.String(), + "secret_name", payload.Name, + ) + + result, err := r.engine.UpdateSecret(user, payload) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "") + } + + return wrapperspb.Bool(result), nil +} + +func (r *RpcServer) DeleteSecret(ctx context.Context, payload *avsproto.DeleteSecretReq) (*wrapperspb.BoolValue, error) { + user, err := r.verifyAuth(ctx) + if err != nil { + return nil, status.Errorf(codes.Unauthenticated, "%s: %s", auth.AuthenticationError, err.Error()) + } + + r.config.Logger.Info("process delete secret", + "user", user.Address.String(), + "secret_name", payload.Name, + ) + + result, err := r.engine.DeleteSecret(user, payload) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "") + } + + return wrapperspb.Bool(result), nil + +} + // Operator action func (r *RpcServer) SyncMessages(payload *avsproto.SyncMessagesReq, srv avsproto.Node_SyncMessagesServer) error { err := r.engine.StreamCheckToOperator(payload, srv) diff --git a/core/taskengine/doc.go b/core/taskengine/doc.go index d22bd62b..396b4278 100644 --- a/core/taskengine/doc.go +++ b/core/taskengine/doc.go @@ -24,5 +24,10 @@ Storage can also be inspect with telnet: telnet /tmp/ap.sock Then issue `get ` or `list ` or `list *` to inspect current keys in the storage. + +**Secret Storage** +- currently org_id will always be _ because we haven't implemented it yet +- workflow_id will also be _ so we can search be prefix +secret:::: -> value */ package taskengine diff --git a/core/taskengine/engine.go b/core/taskengine/engine.go index ac19d333..c46a214e 100644 --- a/core/taskengine/engine.go +++ b/core/taskengine/engine.go @@ -31,8 +31,9 @@ import ( ) const ( - JobTypeExecuteTask = "execute_task" - DefaultItemPerPage = 50 + JobTypeExecuteTask = "execute_task" + DefaultItemPerPage = 50 + MaxSecretNameLength = 255 ) var ( @@ -849,6 +850,100 @@ func (n *Engine) CancelTaskByUser(user *model.User, taskID string) (bool, error) return true, nil } +func (n *Engine) CreateSecret(user *model.User, payload *avsproto.CreateOrUpdateSecretReq) (bool, error) { + secret := &model.Secret{ + User: user, + Name: payload.Name, + Value: payload.Secret, + OrgID: payload.OrgId, + WorkflowID: payload.WorkflowId, + } + + updates := map[string][]byte{} + if strings.HasPrefix(strings.ToLower(payload.Name), "ap_") { + return false, grpcstatus.Errorf(codes.InvalidArgument, "secret name cannot start with ap_") + } + + if len(payload.Name) == 0 || len(payload.Name) > MaxSecretNameLength { + return false, grpcstatus.Errorf(codes.InvalidArgument, "secret name lengh is invalid: should be 1-255 character") + } + + key, _ := SecretStorageKey(secret) + updates[key] = []byte(payload.Secret) + err := n.db.BatchWrite(updates) + if err == nil { + return true, nil + } + + return false, grpcstatus.Errorf(codes.Internal, "Cannot save data") +} + +func (n *Engine) UpdateSecret(user *model.User, payload *avsproto.CreateOrUpdateSecretReq) (bool, error) { + updates := map[string][]byte{} + secret := &model.Secret{ + User: user, + Name: payload.Name, + Value: payload.Secret, + OrgID: payload.OrgId, + WorkflowID: payload.WorkflowId, + } + key, _ := SecretStorageKey(secret) + if ok, err := n.db.Exist([]byte(key)); !ok || err != nil { + return false, grpcstatus.Errorf(codes.NotFound, "Secret not found") + } + + updates[key] = []byte(payload.Secret) + + err := n.db.BatchWrite(updates) + if err == nil { + return true, nil + } + + return true, nil +} + +// ListSecrets +func (n *Engine) ListSecrets(user *model.User, payload *avsproto.ListSecretsReq) (*avsproto.ListSecretsResp, error) { + prefixes := []string{ + SecretStoragePrefix(user), + } + + result := &avsproto.ListSecretsResp{ + Items: []*avsproto.ListSecretsResp_ResponseSecret{}, + } + + secretKeys, err := n.db.ListKeysMulti(prefixes) + if err != nil { + return nil, err + } + for _, k := range secretKeys { + secretWithNameOnly := SecretNameFromKey(k) + item := &avsproto.ListSecretsResp_ResponseSecret{ + Name: secretWithNameOnly.Name, + OrgId: secretWithNameOnly.OrgID, + WorkflowId: secretWithNameOnly.WorkflowID, + } + + result.Items = append(result.Items, item) + } + + return result, nil +} + +func (n *Engine) DeleteSecret(user *model.User, payload *avsproto.DeleteSecretReq) (bool, error) { + // No need to check permission, the key is prefixed by user eoa already + secret := &model.Secret{ + Name: payload.Name, + User: user, + OrgID: payload.OrgId, + WorkflowID: payload.WorkflowId, + } + key, _ := SecretStorageKey(secret) + err := n.db.Delete([]byte(key)) + + return err == nil, err +} + // A global counter for the task engine func (n *Engine) NewSeqID() (string, error) { num := uint64(0) diff --git a/core/taskengine/engine_test.go b/core/taskengine/engine_test.go index df28b4ac..fc130281 100644 --- a/core/taskengine/engine_test.go +++ b/core/taskengine/engine_test.go @@ -7,6 +7,7 @@ import ( "github.com/AvaProtocol/ap-avs/core/apqueue" "github.com/AvaProtocol/ap-avs/core/testutil" + "github.com/AvaProtocol/ap-avs/model" avsproto "github.com/AvaProtocol/ap-avs/protobuf" "github.com/AvaProtocol/ap-avs/storage" ) @@ -440,7 +441,6 @@ func TestTriggerCompletedTaskReturnError(t *testing.T) { t.Errorf("expected trigger succesfully but got error: %s", err) } - fmt.Println(resultTrigger) // Now the task has reach its max run, and canot run anymore resultTrigger, err = n.TriggerTask(testutil.TestUser1(), &avsproto.UserTriggerTaskReq{ TaskId: result.Id, @@ -453,5 +453,323 @@ func TestTriggerCompletedTaskReturnError(t *testing.T) { if err == nil || resultTrigger != nil { t.Errorf("expect trigger error but succeed") } +} + +func TestCreateSecret(t *testing.T) { + db := testutil.TestMustDB() + defer storage.Destroy(db.(*storage.BadgerStorage)) + + config := testutil.GetAggregatorConfig() + n := New(db, config, nil, testutil.GetLogger()) + + user := testutil.TestUser1() + n.CreateSecret(user, &avsproto.CreateOrUpdateSecretReq{ + Name: "telebot", + Secret: "123", + }) + + result, _ := n.ListSecrets(user, &avsproto.ListSecretsReq{}) + if len(result.Items) != 1 { + t.Errorf("invalid secret result, expect 1 item got %d", len(result.Items)) + } + + if result.Items[0].Name != "telebot" { + t.Errorf("invalid secret name, expect telebot got %s", result.Items[0].Name) + } +} + +func TestCreateSecretAtCorrectLevel(t *testing.T) { + db := testutil.TestMustDB() + defer storage.Destroy(db.(*storage.BadgerStorage)) + + config := testutil.GetAggregatorConfig() + n := New(db, config, nil, testutil.GetLogger()) + + user1 := testutil.TestUser1() + user2 := testutil.TestUser2() + n.CreateSecret(user1, &avsproto.CreateOrUpdateSecretReq{ + Name: "svckey", + Secret: "secret123", + }) + + n.CreateSecret(user2, &avsproto.CreateOrUpdateSecretReq{ + Name: "svckey", + Secret: "secret456", + WorkflowId: "workflow123", + }) + + //"secret:_:%s:_:%s", + key1, _ := n.db.GetKey([]byte(fmt.Sprintf("secret:_:%s:_:%s", strings.ToLower(user1.Address.Hex()), "svckey"))) + if string(key1) != "secret123" { + t.Errorf("expect secret to be create at user level with value secret123 but got %s", string(key1)) + } + key2, _ := n.db.GetKey([]byte(fmt.Sprintf("secret:_:%s:%s:%s", strings.ToLower(user2.Address.Hex()), "workflow123", "svckey"))) + if string(key2) != "secret456" { + t.Errorf("expect secret to be create at user level with value secret456 but got %s", string(key1)) + } +} + +func TestCreateSecretListMulti(t *testing.T) { + db := testutil.TestMustDB() + defer storage.Destroy(db.(*storage.BadgerStorage)) + + config := testutil.GetAggregatorConfig() + n := New(db, config, nil, testutil.GetLogger()) + + user := testutil.TestUser1() + n.CreateSecret(user, &avsproto.CreateOrUpdateSecretReq{ + Name: "telebot", + Secret: "123", + }) + + n.CreateSecret(user, &avsproto.CreateOrUpdateSecretReq{ + Name: "telebot2", + Secret: "456", + }) + + result, _ := n.ListSecrets(user, &avsproto.ListSecretsReq{}) + if len(result.Items) != 2 { + t.Errorf("invalid secret result, expect 2 items got %d", len(result.Items)) + } + + if result.Items[0].Name != "telebot" || result.Items[1].Name != "telebot2" { + t.Errorf("invalid secret name, expect [telebot, telebot2] got %s", result) + } +} + +func TestUpdateSecretSucceed(t *testing.T) { + db := testutil.TestMustDB() + defer storage.Destroy(db.(*storage.BadgerStorage)) + + config := testutil.GetAggregatorConfig() + n := New(db, config, nil, testutil.GetLogger()) + + user := testutil.TestUser1() + n.CreateSecret(user, &avsproto.CreateOrUpdateSecretReq{ + Name: "telebot", + Secret: "123", + }) + + key, err := SecretStorageKey(&model.Secret{ + User: user, + Name: "telebot", + }) + + value, err := db.GetKey([]byte(key)) + + if err != nil { + t.Errorf("expect secret existed but found error %s", err) + } + + n.UpdateSecret(user, &avsproto.CreateOrUpdateSecretReq{ + Name: "telebot", + Secret: "4567", + }) + + value, err = db.GetKey([]byte(key)) + + if err != nil { + t.Errorf("expect secret existed but found error %s", err) + } + if string(value) != "4567" { + t.Errorf("expect secrect value is 4567 but got %s", string(value)) + } +} + +func TestCannotUpdateSecretOfOther(t *testing.T) { + db := testutil.TestMustDB() + defer storage.Destroy(db.(*storage.BadgerStorage)) + + config := testutil.GetAggregatorConfig() + n := New(db, config, nil, testutil.GetLogger()) + + user1 := testutil.TestUser1() + user2 := testutil.TestUser2() + n.CreateSecret(user1, &avsproto.CreateOrUpdateSecretReq{ + Name: "telebot", + Secret: "123", + }) + + n.UpdateSecret(user2, &avsproto.CreateOrUpdateSecretReq{ + Name: "telebot", + Secret: "4567", + }) + + key, err := SecretStorageKey(&model.Secret{ + User: user1, + Name: "telebot", + }) + + value, err := db.GetKey([]byte(key)) + + if err != nil { + t.Errorf("expect secret existed but found error %s", err) + } + if string(value) != "123" { + t.Errorf("expect secrect value is 4567 but got %s", string(value)) + } +} + +func TestCannotUpdateNotExistSecret(t *testing.T) { + db := testutil.TestMustDB() + defer storage.Destroy(db.(*storage.BadgerStorage)) + + config := testutil.GetAggregatorConfig() + n := New(db, config, nil, testutil.GetLogger()) + + user1 := testutil.TestUser1() + result, err := n.UpdateSecret(user1, &avsproto.CreateOrUpdateSecretReq{ + Name: "telebot", + Secret: "4567", + }) + + if result || err == nil || err.Error() != "rpc error: code = NotFound desc = Secret not found" { + t.Errorf("expect a failure when updating secret but no error was raise: %s", err) + } +} + +func TestDeleteSecretSucceed(t *testing.T) { + db := testutil.TestMustDB() + defer storage.Destroy(db.(*storage.BadgerStorage)) + + config := testutil.GetAggregatorConfig() + n := New(db, config, nil, testutil.GetLogger()) + + user := testutil.TestUser1() + n.CreateSecret(user, &avsproto.CreateOrUpdateSecretReq{ + Name: "telebot", + Secret: "123", + }) + + // Ensure the secet is created + result, _ := n.ListSecrets(user, &avsproto.ListSecretsReq{}) + if result.Items[0].Name != "telebot" { + t.Errorf("invalid secret name, expect telebot got %s", result) + } + + // Now the user can remove it + n.DeleteSecret(user, &avsproto.DeleteSecretReq{ + Name: "telebot", + }) + + result, _ = n.ListSecrets(user, &avsproto.ListSecretsReq{}) + if len(result.Items) != 0 { + t.Errorf("secret should be delete but still accessible") + } +} + +func TestDeleteSecretAtCorrectUserLevel(t *testing.T) { + db := testutil.TestMustDB() + defer storage.Destroy(db.(*storage.BadgerStorage)) + + config := testutil.GetAggregatorConfig() + n := New(db, config, nil, testutil.GetLogger()) + + user1 := testutil.TestUser1() + n.CreateSecret(user1, &avsproto.CreateOrUpdateSecretReq{ + Name: "svckey", + Secret: "secret123", + }) + + n.CreateSecret(user1, &avsproto.CreateOrUpdateSecretReq{ + Name: "svckey", + Secret: "secret456", + WorkflowId: "workflow123", + }) + + n.DeleteSecret(user1, &avsproto.DeleteSecretReq{ + Name: "svckey", + }) + + key1 := fmt.Sprintf("secret:_:%s:_:%s", strings.ToLower(user1.Address.Hex()), "svckey") + key2 := fmt.Sprintf("secret:_:%s:%s:%s", strings.ToLower(user1.Address.Hex()), "workflow123", "svckey") + + if ok, _ := n.db.Exist([]byte(key1)); ok { + t.Errorf("expect secret to be deleted at user level but it still exists") + } + + if ok, _ := n.db.Exist([]byte(key2)); !ok { + t.Errorf("expect secret to be deleted at workflow level but it doesn't") + } +} + +func TestDeleteSecretAtCorrectWorkflowLevel(t *testing.T) { + db := testutil.TestMustDB() + defer storage.Destroy(db.(*storage.BadgerStorage)) + + config := testutil.GetAggregatorConfig() + n := New(db, config, nil, testutil.GetLogger()) + + user1 := testutil.TestUser1() + n.CreateSecret(user1, &avsproto.CreateOrUpdateSecretReq{ + Name: "svckey", + Secret: "secret123", + }) + + n.CreateSecret(user1, &avsproto.CreateOrUpdateSecretReq{ + Name: "svckey", + Secret: "secret456", + WorkflowId: "workflow123", + }) + + n.DeleteSecret(user1, &avsproto.DeleteSecretReq{ + Name: "svckey", + WorkflowId: "workflow123", + }) + + key1 := fmt.Sprintf("secret:_:%s:_:%s", strings.ToLower(user1.Address.Hex()), "svckey") + key2 := fmt.Sprintf("secret:_:%s:%s:%s", strings.ToLower(user1.Address.Hex()), "workflow123", "svckey") + + if ok, _ := n.db.Exist([]byte(key1)); !ok { + t.Errorf("expect secret to be deleted at user level but it still exists") + } + + if ok, _ := n.db.Exist([]byte(key2)); ok { + t.Errorf("expect secret to be deleted at workflow level but it doesn't") + } +} + +func TestListSecrets(t *testing.T) { + db := testutil.TestMustDB() + defer storage.Destroy(db.(*storage.BadgerStorage)) + + config := testutil.GetAggregatorConfig() + n := New(db, config, nil, testutil.GetLogger()) + + user1 := testutil.TestUser1() + user2 := testutil.TestUser2() + n.CreateSecret(user1, &avsproto.CreateOrUpdateSecretReq{ + Name: "telebot", + Secret: "secret123", + }) + + n.CreateSecret(user1, &avsproto.CreateOrUpdateSecretReq{ + Name: "telebot2", + Secret: "secretworkflow123", + WorkflowId: "workflow123", + }) + + n.CreateSecret(user2, &avsproto.CreateOrUpdateSecretReq{ + Name: "token123", + Secret: "secretworkflow456", + WorkflowId: "worflow123", + }) + + result, _ := n.ListSecrets(user1, &avsproto.ListSecretsReq{}) + fmt.Println(result) + if len(result.Items) != 2 { + t.Errorf("invalid secret result, expect 2 items got %d", len(result.Items)) + } + if result.Items[0].Name != "telebot" || result.Items[1].Name != "telebot2" { + t.Errorf("invalid secret name, expect [telebot, telebot2] got %s", result) + } + + result2, _ := n.ListSecrets(user2, &avsproto.ListSecretsReq{}) + if len(result2.Items) != 1 { + t.Errorf("invalid secret result, expect 2 items got %d", len(result.Items)) + } + if result2.Items[0].Name != "token123" { + t.Errorf("invalid secret name, expect [token123] got %s", result) + } } diff --git a/core/taskengine/executor.go b/core/taskengine/executor.go index 7ec2ec9a..0c1ca8a2 100644 --- a/core/taskengine/executor.go +++ b/core/taskengine/executor.go @@ -80,6 +80,8 @@ func (x *TaskExecutor) RunTask(task *model.Task, queueData *QueueExecutionData) triggerMetadata := queueData.TriggerMetadata vm, err := NewVMWithData(task.Id, task.Trigger, triggerMetadata, task.Nodes, task.Edges) + vm.secrets, _ = LoadSecretForTask(x.db, task) + if err != nil { return nil, err } diff --git a/core/taskengine/schema.go b/core/taskengine/schema.go index 94e4ba27..77f32ca3 100644 --- a/core/taskengine/schema.go +++ b/core/taskengine/schema.go @@ -103,3 +103,68 @@ func TaskStatusToStorageKey(v avsproto.TaskStatus) string { return "a" } + +func SecretStorageKey(secret *model.Secret) (string, error) { + user := secret.User + if user == nil { + return "", fmt.Errorf("Secret is missing required user field") + } + + key := "" + if secret.WorkflowID != "" { + // Ensure the workflow belongs to this user + key = string(SecretStorageKeyForWorkflow(user, secret.Name, secret.WorkflowID)) + } else if secret.OrgID != "" { + key = string(SecretStorageKeyForOrg(user, secret.OrgID, secret.Name)) + } else { + key = string(SecretStorageKeyForUser(user, secret.Name)) + } + return key, nil +} + +func SecretStorageKeyForUser(u *model.User, name string) string { + return fmt.Sprintf( + "secret:_:%s:_:%s", + strings.ToLower(u.Address.Hex()), + name, + ) +} +func SecretStorageKeyForOrg(u *model.User, org string, name string) string { + return fmt.Sprintf( + "secret:%s:%s:_:%s", + org, + strings.ToLower(u.Address.Hex()), + name, + ) +} +func SecretStorageKeyForWorkflow(u *model.User, name string, workflow string) string { + return fmt.Sprintf( + "secret:_:%s:%s:%s", + strings.ToLower(u.Address.Hex()), + workflow, + name, + ) +} +func SecretStoragePrefix(u *model.User) string { + return fmt.Sprintf("secret:_:%s", strings.ToLower(u.Address.Hex())) +} + +// A key had this format secret::0xd7050816337a3f8f690f8083b5ff8019d50c0e50::telebot2 +// example secret:_:0xd7050816337a3f8f690f8083b5ff8019d50c0e50:_:telebot2 secret for all workflow +// example secret:_:0xd7050816337a3f8f690f8083b5ff8019d50c0e50:workflow1234:telebot2 secret for workflow1234 +func SecretNameFromKey(key string) *model.Secret { + parts := strings.Split(key, ":") + secretWithNameOnly := &model.Secret{ + Name: parts[4], + } + + if parts[1] != "_" { + secretWithNameOnly.OrgID = parts[1] + } + + if parts[3] != "_" { + secretWithNameOnly.WorkflowID = parts[3] + } + + return secretWithNameOnly +} diff --git a/core/taskengine/secret.go b/core/taskengine/secret.go new file mode 100644 index 00000000..60e3b0e7 --- /dev/null +++ b/core/taskengine/secret.go @@ -0,0 +1,62 @@ +package taskengine + +import ( + "fmt" + "maps" + + "github.com/AvaProtocol/ap-avs/model" + "github.com/AvaProtocol/ap-avs/storage" + "github.com/ethereum/go-ethereum/common" +) + +func LoadSecretForTask(db storage.Storage, task *model.Task) (map[string]string, error) { + secrets := map[string]string{} + + if task.Owner == "" { + return nil, fmt.Errorf("missing user in task structure") + } + + user := &model.User{ + Address: common.HexToAddress(task.Owner), + } + + prefixes := []string{ + SecretStoragePrefix(user), + } + + secretKeys, err := db.ListKeysMulti(prefixes) + if err != nil { + return nil, err + } + // Copy global static secret we loaded from config file. + maps.Copy(secrets, macroSecrets) + + // Load secret at user level. It has higher priority + // TODO: load secret at org level first, when we introduce that + for _, k := range secretKeys { + secretWithNameOnly := SecretNameFromKey(k) + if secretWithNameOnly.WorkflowID == "" { + if value, err := db.GetKey([]byte(k)); err == nil { + secrets[secretWithNameOnly.Name] = string(value) + } + } + } + + // Now we get secret at workflow level, the lowest level. + for _, k := range secretKeys { + secretWithNameOnly := SecretNameFromKey(k) + if _, ok := secrets[secretWithNameOnly.Name]; ok { + // Our priority is define in this issue: https://github.com/AvaProtocol/EigenLayer-AVS/issues/104#issue-2793661337 + // Regarding the scope of permissions, the top level permission could always overwrite lower levels. For example, org > user > workflow + continue + } + + if secretWithNameOnly.WorkflowID == task.Id { + if value, err := db.GetKey([]byte(k)); err == nil { + secrets[secretWithNameOnly.Name] = string(value) + } + } + } + + return secrets, nil +} diff --git a/core/taskengine/secret_test.go b/core/taskengine/secret_test.go new file mode 100644 index 00000000..c485a6f4 --- /dev/null +++ b/core/taskengine/secret_test.go @@ -0,0 +1,61 @@ +package taskengine + +import ( + "reflect" + "testing" + + "github.com/AvaProtocol/ap-avs/core/testutil" + "github.com/AvaProtocol/ap-avs/model" + avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/ap-avs/storage" +) + +func TestLoadSecretForTask(t *testing.T) { + db := testutil.TestMustDB() + defer storage.Destroy(db.(*storage.BadgerStorage)) + + config := testutil.GetAggregatorConfig() + n := New(db, config, nil, testutil.GetLogger()) + + user1 := testutil.TestUser1() + n.CreateSecret(user1, &avsproto.CreateOrUpdateSecretReq{ + Name: "secret1", + Secret: "mykey1", + }) + + n.CreateSecret(user1, &avsproto.CreateOrUpdateSecretReq{ + Name: "secret1", + Secret: "secretworkflow123", + WorkflowId: "workflow123", + }) + + n.CreateSecret(user1, &avsproto.CreateOrUpdateSecretReq{ + Name: "secret2", + Secret: "mykey2", + WorkflowId: "workflow123", + }) + + n.CreateSecret(user1, &avsproto.CreateOrUpdateSecretReq{ + Name: "secret3", + Secret: "mykey2", + WorkflowId: "worklow456", + }) + + secrets, err := LoadSecretForTask(db, &model.Task{ + &avsproto.Task{ + Owner: user1.Address.Hex(), + Id: "workflow123", + }, + }) + + if err != nil { + t.Errorf("expect no error fetching secret but got error: %s", err) + } + + if !reflect.DeepEqual(map[string]string{ + "secret1": "mykey1", + "secret2": "mykey2", + }, secrets) { + t.Errorf("expect found secrets map[secret1:mykey1 secret2:mykey2] but got %v", secrets) + } +} diff --git a/core/taskengine/vm.go b/core/taskengine/vm.go index 881ec65e..8df79a94 100644 --- a/core/taskengine/vm.go +++ b/core/taskengine/vm.go @@ -66,6 +66,9 @@ type VM struct { // internal state that is set through out program execution vars map[string]any + // hold the name->value of loaded secret for this workflow + secrets map[string]string + plans map[string]*Step entrypoint string instructionCount int64 @@ -78,6 +81,7 @@ func NewVM() *VM { Status: VMStateInitialize, mu: &sync.Mutex{}, instructionCount: 0, + secrets: map[string]string{}, } return v @@ -137,6 +141,7 @@ func NewVMWithData(taskID string, trigger *avsproto.TaskTrigger, triggerMetadata plans: make(map[string]*Step), mu: &sync.Mutex{}, instructionCount: 0, + secrets: map[string]string{}, } for _, node := range nodes { @@ -348,10 +353,23 @@ func (v *VM) runRestApi(stepID string, nodeValue *avsproto.RestAPINode) (*avspro NodeId: stepID, } + // TODO: for global secret, we NEED to limit apikey to only send to a certain authorized endpoint for a certain secret to avoid leakage + if strings.Contains(nodeValue.Url, "${{") { + nodeValue.Url = macros.RenderSecrets(nodeValue.Url, v.secrets) + } + if strings.Contains(nodeValue.Body, "${{") { + nodeValue.Body = macros.RenderSecrets(nodeValue.Body, v.secrets) + } + for headerName, headerValue := range nodeValue.Headers { + if strings.Contains(headerValue, "${{") { + nodeValue.Headers[headerName] = macros.RenderSecrets(headerValue, v.secrets) + } + } + // only evaluate string when there is string interpolation if nodeValue.Body != "" && (strings.Contains(nodeValue.Body, "$") || strings.Contains(nodeValue.Body, "`")) { nodeValue2 := &avsproto.RestAPINode{ - Url: macros.RenderSecrets(nodeValue.Url, macroSecrets), + Url: nodeValue.Url, Headers: nodeValue.Headers, Method: nodeValue.Method, Body: strings.Clone(nodeValue.Body), diff --git a/core/taskengine/vm_test.go b/core/taskengine/vm_test.go index 356e1742..20c21380 100644 --- a/core/taskengine/vm_test.go +++ b/core/taskengine/vm_test.go @@ -556,3 +556,64 @@ func TestParseEntrypointRegardlessOfOrdering(t *testing.T) { t.Errorf("expect entrypoint is notification1 but got %v", vm.entrypoint) } } + +func TestRunTaskWithCustomUserSecret(t *testing.T) { + nodes := []*avsproto.TaskNode{ + &avsproto.TaskNode{ + Id: "123", + Name: "httpnode", + TaskType: &avsproto.TaskNode_RestApi{ + RestApi: &avsproto.RestAPINode{ + Url: "https://httpbin.org/post?apikey=${{secrets.apikey}}", + Method: "POST", + Body: "my key is ${{secrets.apikey}} in body", + }, + }, + }, + } + + trigger := &avsproto.TaskTrigger{ + Id: "triggertest", + Name: "triggertest", + } + + edges := []*avsproto.TaskEdge{ + &avsproto.TaskEdge{ + Id: "e1", + Source: trigger.Id, + Target: "123", + }, + } + + vm, err := NewVMWithData("123", trigger, nil, nodes, edges) + vm.secrets = map[string]string{ + "apikey": "secretapikey", + } + + if err != nil { + t.Errorf("expect vm initialized") + } + + vm.Compile() + + if vm.entrypoint != "123" { + t.Errorf("Error compute entrypoint. Expected 123 Got %s", vm.entrypoint) + } + err = vm.Run() + if err != nil { + t.Errorf("Error executing program. Expected no error Got error %v", err) + } + + if !strings.Contains(vm.ExecutionLogs[0].Log, "Execute") { + t.Errorf("error generating log for executing. expect a log line displaying the request attempt, got nothing") + } + + data := vm.vars["httpnode"].(map[string]any) + if data["data"].(string) != "my key is secretapikey in body" { + t.Errorf("secret doesn't render correctly in body, expect secretapikey but got %S", data["data"]) + } + + if data["args"].(map[string]interface{})["apikey"].(string) != "secretapikey" { + t.Errorf("secret doesn't render correctly in uri, expect secretapikey but got %S", data["data"]) + } +} diff --git a/model/secret.go b/model/secret.go new file mode 100644 index 00000000..ca9cc5e4 --- /dev/null +++ b/model/secret.go @@ -0,0 +1,18 @@ +package model + +type Secret struct { + Name string `validate:"required"` + Value string `validate:"required"` + + // User is the original EOA that create the secret + User *User `validate:"required"` + + // We support 3 scopes currently + // - org + // - user + // - workflow + Scope string `validate:"oneof=user org workflow"` + + OrgID string + WorkflowID string +} diff --git a/protobuf/avs.pb.go b/protobuf/avs.pb.go index b4b9c897..0f56c68f 100644 --- a/protobuf/avs.pb.go +++ b/protobuf/avs.pb.go @@ -3169,6 +3169,243 @@ func (x *UserTriggerTaskResp) GetStatus() ExecutionStatus { return ExecutionStatus_Queued } +type CreateOrUpdateSecretReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name of the secret. it should be [a-zA-Z0-9_]+ + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // value can be any valid unicode string + // Secret is the only thing we can change in an update. workflow and org id cannot be change + Secret string `protobuf:"bytes,2,opt,name=secret,proto3" json:"secret,omitempty"` + // A secret when define can be at these level + // - org: available to everything in the org. Currently this isn't supported yet. reserve for future use + // - user: available to all workflow of an user. This is the default level + // - workflow: available to a single workflow. To make a secret available to multiple workflow, either use org/user level or define them on other workflow. + WorkflowId string `protobuf:"bytes,3,opt,name=workflow_id,json=workflowId,proto3" json:"workflow_id,omitempty"` + OrgId string `protobuf:"bytes,4,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"` +} + +func (x *CreateOrUpdateSecretReq) Reset() { + *x = CreateOrUpdateSecretReq{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_avs_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateOrUpdateSecretReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateOrUpdateSecretReq) ProtoMessage() {} + +func (x *CreateOrUpdateSecretReq) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_avs_proto_msgTypes[40] + 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 CreateOrUpdateSecretReq.ProtoReflect.Descriptor instead. +func (*CreateOrUpdateSecretReq) Descriptor() ([]byte, []int) { + return file_protobuf_avs_proto_rawDescGZIP(), []int{40} +} + +func (x *CreateOrUpdateSecretReq) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateOrUpdateSecretReq) GetSecret() string { + if x != nil { + return x.Secret + } + return "" +} + +func (x *CreateOrUpdateSecretReq) GetWorkflowId() string { + if x != nil { + return x.WorkflowId + } + return "" +} + +func (x *CreateOrUpdateSecretReq) GetOrgId() string { + if x != nil { + return x.OrgId + } + return "" +} + +type ListSecretsReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + WorkflowId string `protobuf:"bytes,1,opt,name=workflow_id,json=workflowId,proto3" json:"workflow_id,omitempty"` +} + +func (x *ListSecretsReq) Reset() { + *x = ListSecretsReq{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_avs_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListSecretsReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListSecretsReq) ProtoMessage() {} + +func (x *ListSecretsReq) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_avs_proto_msgTypes[41] + 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 ListSecretsReq.ProtoReflect.Descriptor instead. +func (*ListSecretsReq) Descriptor() ([]byte, []int) { + return file_protobuf_avs_proto_rawDescGZIP(), []int{41} +} + +func (x *ListSecretsReq) GetWorkflowId() string { + if x != nil { + return x.WorkflowId + } + return "" +} + +type ListSecretsResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Items []*ListSecretsResp_ResponseSecret `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` +} + +func (x *ListSecretsResp) Reset() { + *x = ListSecretsResp{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_avs_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListSecretsResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListSecretsResp) ProtoMessage() {} + +func (x *ListSecretsResp) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_avs_proto_msgTypes[42] + 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 ListSecretsResp.ProtoReflect.Descriptor instead. +func (*ListSecretsResp) Descriptor() ([]byte, []int) { + return file_protobuf_avs_proto_rawDescGZIP(), []int{42} +} + +func (x *ListSecretsResp) GetItems() []*ListSecretsResp_ResponseSecret { + if x != nil { + return x.Items + } + return nil +} + +type DeleteSecretReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Delete the secret belong to the specific workflow. Without its, we delete the one belong to user + WorkflowId string `protobuf:"bytes,2,opt,name=workflow_id,json=workflowId,proto3" json:"workflow_id,omitempty"` + // Delete the secret belong to the specific prg. Without its, we delete the one belong to user + OrgId string `protobuf:"bytes,3,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"` +} + +func (x *DeleteSecretReq) Reset() { + *x = DeleteSecretReq{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_avs_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteSecretReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteSecretReq) ProtoMessage() {} + +func (x *DeleteSecretReq) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_avs_proto_msgTypes[43] + 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 DeleteSecretReq.ProtoReflect.Descriptor instead. +func (*DeleteSecretReq) Descriptor() ([]byte, []int) { + return file_protobuf_avs_proto_rawDescGZIP(), []int{43} +} + +func (x *DeleteSecretReq) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DeleteSecretReq) GetWorkflowId() string { + if x != nil { + return x.WorkflowId + } + return "" +} + +func (x *DeleteSecretReq) GetOrgId() string { + if x != nil { + return x.OrgId + } + return "" +} + type EventCondition_Matcher struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3203,7 +3440,7 @@ type EventCondition_Matcher struct { func (x *EventCondition_Matcher) Reset() { *x = EventCondition_Matcher{} if protoimpl.UnsafeEnabled { - mi := &file_protobuf_avs_proto_msgTypes[40] + mi := &file_protobuf_avs_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3216,7 +3453,7 @@ func (x *EventCondition_Matcher) String() string { func (*EventCondition_Matcher) ProtoMessage() {} func (x *EventCondition_Matcher) ProtoReflect() protoreflect.Message { - mi := &file_protobuf_avs_proto_msgTypes[40] + mi := &file_protobuf_avs_proto_msgTypes[44] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3264,7 +3501,7 @@ type Execution_Step struct { func (x *Execution_Step) Reset() { *x = Execution_Step{} if protoimpl.UnsafeEnabled { - mi := &file_protobuf_avs_proto_msgTypes[43] + mi := &file_protobuf_avs_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3277,7 +3514,7 @@ func (x *Execution_Step) String() string { func (*Execution_Step) ProtoMessage() {} func (x *Execution_Step) ProtoReflect() protoreflect.Message { - mi := &file_protobuf_avs_proto_msgTypes[43] + mi := &file_protobuf_avs_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3369,7 +3606,7 @@ type ListTasksResp_Item struct { func (x *ListTasksResp_Item) Reset() { *x = ListTasksResp_Item{} if protoimpl.UnsafeEnabled { - mi := &file_protobuf_avs_proto_msgTypes[44] + mi := &file_protobuf_avs_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3382,7 +3619,7 @@ func (x *ListTasksResp_Item) String() string { func (*ListTasksResp_Item) ProtoMessage() {} func (x *ListTasksResp_Item) ProtoReflect() protoreflect.Message { - mi := &file_protobuf_avs_proto_msgTypes[44] + mi := &file_protobuf_avs_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3482,6 +3719,78 @@ func (x *ListTasksResp_Item) GetTrigger() *TaskTrigger { return nil } +type ListSecretsResp_ResponseSecret struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // when listing secret, we don't return its value, just secret and last update + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Scope string `protobuf:"bytes,2,opt,name=scope,proto3" json:"scope,omitempty"` + WorkflowId string `protobuf:"bytes,4,opt,name=workflow_id,json=workflowId,proto3" json:"workflow_id,omitempty"` + OrgId string `protobuf:"bytes,5,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"` +} + +func (x *ListSecretsResp_ResponseSecret) Reset() { + *x = ListSecretsResp_ResponseSecret{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_avs_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListSecretsResp_ResponseSecret) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListSecretsResp_ResponseSecret) ProtoMessage() {} + +func (x *ListSecretsResp_ResponseSecret) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_avs_proto_msgTypes[49] + 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 ListSecretsResp_ResponseSecret.ProtoReflect.Descriptor instead. +func (*ListSecretsResp_ResponseSecret) Descriptor() ([]byte, []int) { + return file_protobuf_avs_proto_rawDescGZIP(), []int{42, 0} +} + +func (x *ListSecretsResp_ResponseSecret) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ListSecretsResp_ResponseSecret) GetScope() string { + if x != nil { + return x.Scope + } + return "" +} + +func (x *ListSecretsResp_ResponseSecret) GetWorkflowId() string { + if x != nil { + return x.WorkflowId + } + return "" +} + +func (x *ListSecretsResp_ResponseSecret) GetOrgId() string { + if x != nil { + return x.OrgId + } + return "" +} + var File_protobuf_avs_proto protoreflect.FileDescriptor var file_protobuf_avs_proto_rawDesc = []byte{ @@ -3897,88 +4206,137 @@ var file_protobuf_avs_proto_rawDesc = []byte{ 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, - 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2a, - 0xdf, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x6e, 0x6b, - 0x6e, 0x6f, 0x77, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0c, 0x52, 0x70, - 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0xe8, 0x07, 0x12, 0x17, 0x0a, - 0x12, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, - 0x62, 0x6c, 0x65, 0x10, 0xd0, 0x0f, 0x12, 0x16, 0x0a, 0x11, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0xd1, 0x0f, 0x12, 0x18, - 0x0a, 0x13, 0x53, 0x6d, 0x61, 0x72, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x70, 0x63, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0xf0, 0x2e, 0x12, 0x1d, 0x0a, 0x18, 0x53, 0x6d, 0x61, 0x72, - 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x10, 0xf1, 0x2e, 0x12, 0x16, 0x0a, 0x11, 0x54, 0x61, 0x73, 0x6b, 0x44, - 0x61, 0x74, 0x61, 0x43, 0x6f, 0x72, 0x72, 0x75, 0x70, 0x74, 0x65, 0x64, 0x10, 0xd8, 0x36, 0x12, - 0x19, 0x0a, 0x14, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x69, 0x73, 0x73, 0x69, - 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0xd9, 0x36, 0x12, 0x15, 0x0a, 0x10, 0x54, 0x61, - 0x73, 0x6b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0xdb, - 0x36, 0x2a, 0x50, 0x0a, 0x0a, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x0a, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, - 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x61, - 0x69, 0x6c, 0x65, 0x64, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, - 0x65, 0x64, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x10, 0x04, 0x2a, 0x2b, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0a, 0x0a, 0x06, 0x51, 0x75, 0x65, 0x75, 0x65, 0x64, - 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x10, 0x02, - 0x2a, 0x20, 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x64, 0x65, 0x4c, 0x61, - 0x6e, 0x67, 0x12, 0x0e, 0x0a, 0x0a, 0x4a, 0x61, 0x76, 0x61, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x10, 0x00, 0x32, 0x85, 0x07, 0x0a, 0x0a, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, - 0x72, 0x12, 0x36, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x2e, 0x61, 0x67, - 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, - 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, - 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x08, 0x47, 0x65, 0x74, - 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, - 0x6f, 0x72, 0x2e, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x15, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x4e, 0x6f, 0x6e, - 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x57, - 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, - 0x6f, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x1a, - 0x19, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x47, 0x65, 0x74, - 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0b, - 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x19, 0x2e, 0x61, 0x67, - 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x6c, - 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, + 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, + 0x7d, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x22, 0x31, + 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x49, + 0x64, 0x22, 0xc7, 0x01, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x40, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, + 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x1a, 0x72, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, + 0x6f, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, + 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x22, 0x5d, 0x0a, 0x0f, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x2a, 0xdf, 0x01, 0x0a, 0x05, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0c, 0x52, 0x70, 0x63, 0x4e, 0x6f, 0x64, 0x65, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0xe8, 0x07, 0x12, 0x17, 0x0a, 0x12, 0x53, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x10, 0xd0, + 0x0f, 0x12, 0x16, 0x0a, 0x11, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x57, 0x72, 0x69, 0x74, + 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0xd1, 0x0f, 0x12, 0x18, 0x0a, 0x13, 0x53, 0x6d, 0x61, + 0x72, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x70, 0x63, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x10, 0xf0, 0x2e, 0x12, 0x1d, 0x0a, 0x18, 0x53, 0x6d, 0x61, 0x72, 0x74, 0x57, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, + 0xf1, 0x2e, 0x12, 0x16, 0x0a, 0x11, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, + 0x72, 0x72, 0x75, 0x70, 0x74, 0x65, 0x64, 0x10, 0xd8, 0x36, 0x12, 0x19, 0x0a, 0x14, 0x54, 0x61, + 0x73, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x10, 0xd9, 0x36, 0x12, 0x15, 0x0a, 0x10, 0x54, 0x61, 0x73, 0x6b, 0x54, 0x72, 0x69, + 0x67, 0x67, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0xdb, 0x36, 0x2a, 0x50, 0x0a, 0x0a, + 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x64, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, + 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x65, 0x64, 0x10, 0x03, 0x12, + 0x0d, 0x0a, 0x09, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x10, 0x04, 0x2a, 0x2b, + 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x0a, 0x0a, 0x06, 0x51, 0x75, 0x65, 0x75, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0c, 0x0a, + 0x08, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x10, 0x02, 0x2a, 0x20, 0x0a, 0x0e, 0x43, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x64, 0x65, 0x4c, 0x61, 0x6e, 0x67, 0x12, 0x0e, 0x0a, + 0x0a, 0x4a, 0x61, 0x76, 0x61, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x10, 0x00, 0x32, 0xba, 0x09, + 0x0a, 0x0a, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x36, 0x0a, 0x06, + 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, + 0x74, 0x6f, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, + 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, + 0x12, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x4e, 0x6f, + 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x61, 0x67, 0x67, + 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x12, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x47, 0x65, + 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x61, 0x67, 0x67, + 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x57, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x19, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, - 0x73, 0x6b, 0x12, 0x19, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, + 0x71, 0x1a, 0x1a, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, + 0x45, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x19, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x09, 0x4c, - 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, - 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, - 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, - 0x30, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x11, 0x2e, 0x61, 0x67, 0x67, - 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x49, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, - 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x22, - 0x00, 0x12, 0x51, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x1d, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x71, 0x1a, 0x1e, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, - 0x72, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x15, - 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x45, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x2e, - 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, - 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x0a, 0x43, 0x61, - 0x6e, 0x63, 0x65, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x11, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, - 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x49, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, - 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x0a, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x11, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, - 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x49, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, + 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, + 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, + 0x73, 0x6b, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, + 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, + 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x30, 0x0a, 0x07, 0x47, 0x65, + 0x74, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x11, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, + 0x6f, 0x72, 0x2e, 0x49, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, + 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0e, + 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1d, + 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1e, 0x2e, + 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, + 0x41, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x67, 0x67, 0x72, + 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x00, 0x12, 0x51, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, + 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x0a, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x54, + 0x61, 0x73, 0x6b, 0x12, 0x11, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, + 0x2e, 0x49, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, + 0x73, 0x6b, 0x12, 0x11, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, + 0x49, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x54, 0x61, + 0x73, 0x6b, 0x12, 0x1e, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, + 0x55, 0x73, 0x65, 0x72, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x52, + 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, + 0x55, 0x73, 0x65, 0x72, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x52, + 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x23, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, + 0x6f, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, - 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0b, 0x54, 0x72, 0x69, 0x67, - 0x67, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x1e, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, - 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, - 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, - 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, - 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, + 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x12, 0x1b, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x1a, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, + 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x61, + 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, + 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x23, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, + 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, + 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x61, 0x76, 0x73, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } @@ -3995,69 +4353,74 @@ func file_protobuf_avs_proto_rawDescGZIP() []byte { } var file_protobuf_avs_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_protobuf_avs_proto_msgTypes = make([]protoimpl.MessageInfo, 45) +var file_protobuf_avs_proto_msgTypes = make([]protoimpl.MessageInfo, 50) var file_protobuf_avs_proto_goTypes = []interface{}{ - (Error)(0), // 0: aggregator.Error - (TaskStatus)(0), // 1: aggregator.TaskStatus - (ExecutionStatus)(0), // 2: aggregator.ExecutionStatus - (CustomCodeLang)(0), // 3: aggregator.CustomCodeLang - (TriggerMetadata_TriggerType)(0), // 4: aggregator.TriggerMetadata.TriggerType - (*IdReq)(nil), // 5: aggregator.IdReq - (*FixedTimeCondition)(nil), // 6: aggregator.FixedTimeCondition - (*CronCondition)(nil), // 7: aggregator.CronCondition - (*BlockCondition)(nil), // 8: aggregator.BlockCondition - (*EventCondition)(nil), // 9: aggregator.EventCondition - (*TaskTrigger)(nil), // 10: aggregator.TaskTrigger - (*ETHTransferNode)(nil), // 11: aggregator.ETHTransferNode - (*ContractWriteNode)(nil), // 12: aggregator.ContractWriteNode - (*ContractReadNode)(nil), // 13: aggregator.ContractReadNode - (*GraphQLQueryNode)(nil), // 14: aggregator.GraphQLQueryNode - (*RestAPINode)(nil), // 15: aggregator.RestAPINode - (*CustomCodeNode)(nil), // 16: aggregator.CustomCodeNode - (*Condition)(nil), // 17: aggregator.Condition - (*BranchNode)(nil), // 18: aggregator.BranchNode - (*FilterNode)(nil), // 19: aggregator.FilterNode - (*LoopNode)(nil), // 20: aggregator.LoopNode - (*TaskEdge)(nil), // 21: aggregator.TaskEdge - (*TaskNode)(nil), // 22: aggregator.TaskNode - (*Execution)(nil), // 23: aggregator.Execution - (*Task)(nil), // 24: aggregator.Task - (*CreateTaskReq)(nil), // 25: aggregator.CreateTaskReq - (*CreateTaskResp)(nil), // 26: aggregator.CreateTaskResp - (*NonceRequest)(nil), // 27: aggregator.NonceRequest - (*NonceResp)(nil), // 28: aggregator.NonceResp - (*ListWalletReq)(nil), // 29: aggregator.ListWalletReq - (*SmartWallet)(nil), // 30: aggregator.SmartWallet - (*ListWalletResp)(nil), // 31: aggregator.ListWalletResp - (*ListTasksReq)(nil), // 32: aggregator.ListTasksReq - (*ListTasksResp)(nil), // 33: aggregator.ListTasksResp - (*ListExecutionsReq)(nil), // 34: aggregator.ListExecutionsReq - (*ListExecutionsResp)(nil), // 35: aggregator.ListExecutionsResp - (*ExecutionReq)(nil), // 36: aggregator.ExecutionReq - (*ExecutionStatusResp)(nil), // 37: aggregator.ExecutionStatusResp - (*GetKeyReq)(nil), // 38: aggregator.GetKeyReq - (*KeyResp)(nil), // 39: aggregator.KeyResp - (*TriggerMetadata)(nil), // 40: aggregator.TriggerMetadata - (*GetWalletReq)(nil), // 41: aggregator.GetWalletReq - (*GetWalletResp)(nil), // 42: aggregator.GetWalletResp - (*UserTriggerTaskReq)(nil), // 43: aggregator.UserTriggerTaskReq - (*UserTriggerTaskResp)(nil), // 44: aggregator.UserTriggerTaskResp - (*EventCondition_Matcher)(nil), // 45: aggregator.EventCondition.Matcher - nil, // 46: aggregator.GraphQLQueryNode.VariablesEntry - nil, // 47: aggregator.RestAPINode.HeadersEntry - (*Execution_Step)(nil), // 48: aggregator.Execution.Step - (*ListTasksResp_Item)(nil), // 49: aggregator.ListTasksResp.Item - (*timestamppb.Timestamp)(nil), // 50: google.protobuf.Timestamp - (*wrapperspb.BoolValue)(nil), // 51: google.protobuf.BoolValue + (Error)(0), // 0: aggregator.Error + (TaskStatus)(0), // 1: aggregator.TaskStatus + (ExecutionStatus)(0), // 2: aggregator.ExecutionStatus + (CustomCodeLang)(0), // 3: aggregator.CustomCodeLang + (TriggerMetadata_TriggerType)(0), // 4: aggregator.TriggerMetadata.TriggerType + (*IdReq)(nil), // 5: aggregator.IdReq + (*FixedTimeCondition)(nil), // 6: aggregator.FixedTimeCondition + (*CronCondition)(nil), // 7: aggregator.CronCondition + (*BlockCondition)(nil), // 8: aggregator.BlockCondition + (*EventCondition)(nil), // 9: aggregator.EventCondition + (*TaskTrigger)(nil), // 10: aggregator.TaskTrigger + (*ETHTransferNode)(nil), // 11: aggregator.ETHTransferNode + (*ContractWriteNode)(nil), // 12: aggregator.ContractWriteNode + (*ContractReadNode)(nil), // 13: aggregator.ContractReadNode + (*GraphQLQueryNode)(nil), // 14: aggregator.GraphQLQueryNode + (*RestAPINode)(nil), // 15: aggregator.RestAPINode + (*CustomCodeNode)(nil), // 16: aggregator.CustomCodeNode + (*Condition)(nil), // 17: aggregator.Condition + (*BranchNode)(nil), // 18: aggregator.BranchNode + (*FilterNode)(nil), // 19: aggregator.FilterNode + (*LoopNode)(nil), // 20: aggregator.LoopNode + (*TaskEdge)(nil), // 21: aggregator.TaskEdge + (*TaskNode)(nil), // 22: aggregator.TaskNode + (*Execution)(nil), // 23: aggregator.Execution + (*Task)(nil), // 24: aggregator.Task + (*CreateTaskReq)(nil), // 25: aggregator.CreateTaskReq + (*CreateTaskResp)(nil), // 26: aggregator.CreateTaskResp + (*NonceRequest)(nil), // 27: aggregator.NonceRequest + (*NonceResp)(nil), // 28: aggregator.NonceResp + (*ListWalletReq)(nil), // 29: aggregator.ListWalletReq + (*SmartWallet)(nil), // 30: aggregator.SmartWallet + (*ListWalletResp)(nil), // 31: aggregator.ListWalletResp + (*ListTasksReq)(nil), // 32: aggregator.ListTasksReq + (*ListTasksResp)(nil), // 33: aggregator.ListTasksResp + (*ListExecutionsReq)(nil), // 34: aggregator.ListExecutionsReq + (*ListExecutionsResp)(nil), // 35: aggregator.ListExecutionsResp + (*ExecutionReq)(nil), // 36: aggregator.ExecutionReq + (*ExecutionStatusResp)(nil), // 37: aggregator.ExecutionStatusResp + (*GetKeyReq)(nil), // 38: aggregator.GetKeyReq + (*KeyResp)(nil), // 39: aggregator.KeyResp + (*TriggerMetadata)(nil), // 40: aggregator.TriggerMetadata + (*GetWalletReq)(nil), // 41: aggregator.GetWalletReq + (*GetWalletResp)(nil), // 42: aggregator.GetWalletResp + (*UserTriggerTaskReq)(nil), // 43: aggregator.UserTriggerTaskReq + (*UserTriggerTaskResp)(nil), // 44: aggregator.UserTriggerTaskResp + (*CreateOrUpdateSecretReq)(nil), // 45: aggregator.CreateOrUpdateSecretReq + (*ListSecretsReq)(nil), // 46: aggregator.ListSecretsReq + (*ListSecretsResp)(nil), // 47: aggregator.ListSecretsResp + (*DeleteSecretReq)(nil), // 48: aggregator.DeleteSecretReq + (*EventCondition_Matcher)(nil), // 49: aggregator.EventCondition.Matcher + nil, // 50: aggregator.GraphQLQueryNode.VariablesEntry + nil, // 51: aggregator.RestAPINode.HeadersEntry + (*Execution_Step)(nil), // 52: aggregator.Execution.Step + (*ListTasksResp_Item)(nil), // 53: aggregator.ListTasksResp.Item + (*ListSecretsResp_ResponseSecret)(nil), // 54: aggregator.ListSecretsResp.ResponseSecret + (*timestamppb.Timestamp)(nil), // 55: google.protobuf.Timestamp + (*wrapperspb.BoolValue)(nil), // 56: google.protobuf.BoolValue } var file_protobuf_avs_proto_depIdxs = []int32{ - 45, // 0: aggregator.EventCondition.matcher:type_name -> aggregator.EventCondition.Matcher + 49, // 0: aggregator.EventCondition.matcher:type_name -> aggregator.EventCondition.Matcher 6, // 1: aggregator.TaskTrigger.fixed_time:type_name -> aggregator.FixedTimeCondition 7, // 2: aggregator.TaskTrigger.cron:type_name -> aggregator.CronCondition 8, // 3: aggregator.TaskTrigger.block:type_name -> aggregator.BlockCondition 9, // 4: aggregator.TaskTrigger.event:type_name -> aggregator.EventCondition - 46, // 5: aggregator.GraphQLQueryNode.variables:type_name -> aggregator.GraphQLQueryNode.VariablesEntry - 47, // 6: aggregator.RestAPINode.headers:type_name -> aggregator.RestAPINode.HeadersEntry + 50, // 5: aggregator.GraphQLQueryNode.variables:type_name -> aggregator.GraphQLQueryNode.VariablesEntry + 51, // 6: aggregator.RestAPINode.headers:type_name -> aggregator.RestAPINode.HeadersEntry 3, // 7: aggregator.CustomCodeNode.lang:type_name -> aggregator.CustomCodeLang 17, // 8: aggregator.BranchNode.conditions:type_name -> aggregator.Condition 11, // 9: aggregator.LoopNode.eth_transfer:type_name -> aggregator.ETHTransferNode @@ -4076,7 +4439,7 @@ var file_protobuf_avs_proto_depIdxs = []int32{ 20, // 22: aggregator.TaskNode.loop:type_name -> aggregator.LoopNode 16, // 23: aggregator.TaskNode.custom_code:type_name -> aggregator.CustomCodeNode 40, // 24: aggregator.Execution.trigger_metadata:type_name -> aggregator.TriggerMetadata - 48, // 25: aggregator.Execution.steps:type_name -> aggregator.Execution.Step + 52, // 25: aggregator.Execution.steps:type_name -> aggregator.Execution.Step 1, // 26: aggregator.Task.status:type_name -> aggregator.TaskStatus 10, // 27: aggregator.Task.trigger:type_name -> aggregator.TaskTrigger 22, // 28: aggregator.Task.nodes:type_name -> aggregator.TaskNode @@ -4085,47 +4448,56 @@ var file_protobuf_avs_proto_depIdxs = []int32{ 22, // 31: aggregator.CreateTaskReq.nodes:type_name -> aggregator.TaskNode 21, // 32: aggregator.CreateTaskReq.edges:type_name -> aggregator.TaskEdge 30, // 33: aggregator.ListWalletResp.items:type_name -> aggregator.SmartWallet - 49, // 34: aggregator.ListTasksResp.items:type_name -> aggregator.ListTasksResp.Item + 53, // 34: aggregator.ListTasksResp.items:type_name -> aggregator.ListTasksResp.Item 23, // 35: aggregator.ListExecutionsResp.items:type_name -> aggregator.Execution 2, // 36: aggregator.ExecutionStatusResp.status:type_name -> aggregator.ExecutionStatus - 50, // 37: aggregator.GetKeyReq.issued_at:type_name -> google.protobuf.Timestamp - 50, // 38: aggregator.GetKeyReq.expired_at:type_name -> google.protobuf.Timestamp + 55, // 37: aggregator.GetKeyReq.issued_at:type_name -> google.protobuf.Timestamp + 55, // 38: aggregator.GetKeyReq.expired_at:type_name -> google.protobuf.Timestamp 4, // 39: aggregator.TriggerMetadata.type:type_name -> aggregator.TriggerMetadata.TriggerType 40, // 40: aggregator.UserTriggerTaskReq.trigger_metadata:type_name -> aggregator.TriggerMetadata 2, // 41: aggregator.UserTriggerTaskResp.status:type_name -> aggregator.ExecutionStatus - 1, // 42: aggregator.ListTasksResp.Item.status:type_name -> aggregator.TaskStatus - 10, // 43: aggregator.ListTasksResp.Item.trigger:type_name -> aggregator.TaskTrigger - 38, // 44: aggregator.Aggregator.GetKey:input_type -> aggregator.GetKeyReq - 27, // 45: aggregator.Aggregator.GetNonce:input_type -> aggregator.NonceRequest - 41, // 46: aggregator.Aggregator.GetWallet:input_type -> aggregator.GetWalletReq - 29, // 47: aggregator.Aggregator.ListWallets:input_type -> aggregator.ListWalletReq - 25, // 48: aggregator.Aggregator.CreateTask:input_type -> aggregator.CreateTaskReq - 32, // 49: aggregator.Aggregator.ListTasks:input_type -> aggregator.ListTasksReq - 5, // 50: aggregator.Aggregator.GetTask:input_type -> aggregator.IdReq - 34, // 51: aggregator.Aggregator.ListExecutions:input_type -> aggregator.ListExecutionsReq - 36, // 52: aggregator.Aggregator.GetExecution:input_type -> aggregator.ExecutionReq - 36, // 53: aggregator.Aggregator.GetExecutionStatus:input_type -> aggregator.ExecutionReq - 5, // 54: aggregator.Aggregator.CancelTask:input_type -> aggregator.IdReq - 5, // 55: aggregator.Aggregator.DeleteTask:input_type -> aggregator.IdReq - 43, // 56: aggregator.Aggregator.TriggerTask:input_type -> aggregator.UserTriggerTaskReq - 39, // 57: aggregator.Aggregator.GetKey:output_type -> aggregator.KeyResp - 28, // 58: aggregator.Aggregator.GetNonce:output_type -> aggregator.NonceResp - 42, // 59: aggregator.Aggregator.GetWallet:output_type -> aggregator.GetWalletResp - 31, // 60: aggregator.Aggregator.ListWallets:output_type -> aggregator.ListWalletResp - 26, // 61: aggregator.Aggregator.CreateTask:output_type -> aggregator.CreateTaskResp - 33, // 62: aggregator.Aggregator.ListTasks:output_type -> aggregator.ListTasksResp - 24, // 63: aggregator.Aggregator.GetTask:output_type -> aggregator.Task - 35, // 64: aggregator.Aggregator.ListExecutions:output_type -> aggregator.ListExecutionsResp - 23, // 65: aggregator.Aggregator.GetExecution:output_type -> aggregator.Execution - 37, // 66: aggregator.Aggregator.GetExecutionStatus:output_type -> aggregator.ExecutionStatusResp - 51, // 67: aggregator.Aggregator.CancelTask:output_type -> google.protobuf.BoolValue - 51, // 68: aggregator.Aggregator.DeleteTask:output_type -> google.protobuf.BoolValue - 44, // 69: aggregator.Aggregator.TriggerTask:output_type -> aggregator.UserTriggerTaskResp - 57, // [57:70] is the sub-list for method output_type - 44, // [44:57] is the sub-list for method input_type - 44, // [44:44] is the sub-list for extension type_name - 44, // [44:44] is the sub-list for extension extendee - 0, // [0:44] is the sub-list for field type_name + 54, // 42: aggregator.ListSecretsResp.items:type_name -> aggregator.ListSecretsResp.ResponseSecret + 1, // 43: aggregator.ListTasksResp.Item.status:type_name -> aggregator.TaskStatus + 10, // 44: aggregator.ListTasksResp.Item.trigger:type_name -> aggregator.TaskTrigger + 38, // 45: aggregator.Aggregator.GetKey:input_type -> aggregator.GetKeyReq + 27, // 46: aggregator.Aggregator.GetNonce:input_type -> aggregator.NonceRequest + 41, // 47: aggregator.Aggregator.GetWallet:input_type -> aggregator.GetWalletReq + 29, // 48: aggregator.Aggregator.ListWallets:input_type -> aggregator.ListWalletReq + 25, // 49: aggregator.Aggregator.CreateTask:input_type -> aggregator.CreateTaskReq + 32, // 50: aggregator.Aggregator.ListTasks:input_type -> aggregator.ListTasksReq + 5, // 51: aggregator.Aggregator.GetTask:input_type -> aggregator.IdReq + 34, // 52: aggregator.Aggregator.ListExecutions:input_type -> aggregator.ListExecutionsReq + 36, // 53: aggregator.Aggregator.GetExecution:input_type -> aggregator.ExecutionReq + 36, // 54: aggregator.Aggregator.GetExecutionStatus:input_type -> aggregator.ExecutionReq + 5, // 55: aggregator.Aggregator.CancelTask:input_type -> aggregator.IdReq + 5, // 56: aggregator.Aggregator.DeleteTask:input_type -> aggregator.IdReq + 43, // 57: aggregator.Aggregator.TriggerTask:input_type -> aggregator.UserTriggerTaskReq + 45, // 58: aggregator.Aggregator.CreateSecret:input_type -> aggregator.CreateOrUpdateSecretReq + 48, // 59: aggregator.Aggregator.Delete:input_type -> aggregator.DeleteSecretReq + 46, // 60: aggregator.Aggregator.ListSecrets:input_type -> aggregator.ListSecretsReq + 45, // 61: aggregator.Aggregator.UpdateSecret:input_type -> aggregator.CreateOrUpdateSecretReq + 39, // 62: aggregator.Aggregator.GetKey:output_type -> aggregator.KeyResp + 28, // 63: aggregator.Aggregator.GetNonce:output_type -> aggregator.NonceResp + 42, // 64: aggregator.Aggregator.GetWallet:output_type -> aggregator.GetWalletResp + 31, // 65: aggregator.Aggregator.ListWallets:output_type -> aggregator.ListWalletResp + 26, // 66: aggregator.Aggregator.CreateTask:output_type -> aggregator.CreateTaskResp + 33, // 67: aggregator.Aggregator.ListTasks:output_type -> aggregator.ListTasksResp + 24, // 68: aggregator.Aggregator.GetTask:output_type -> aggregator.Task + 35, // 69: aggregator.Aggregator.ListExecutions:output_type -> aggregator.ListExecutionsResp + 23, // 70: aggregator.Aggregator.GetExecution:output_type -> aggregator.Execution + 37, // 71: aggregator.Aggregator.GetExecutionStatus:output_type -> aggregator.ExecutionStatusResp + 56, // 72: aggregator.Aggregator.CancelTask:output_type -> google.protobuf.BoolValue + 56, // 73: aggregator.Aggregator.DeleteTask:output_type -> google.protobuf.BoolValue + 44, // 74: aggregator.Aggregator.TriggerTask:output_type -> aggregator.UserTriggerTaskResp + 56, // 75: aggregator.Aggregator.CreateSecret:output_type -> google.protobuf.BoolValue + 56, // 76: aggregator.Aggregator.Delete:output_type -> google.protobuf.BoolValue + 47, // 77: aggregator.Aggregator.ListSecrets:output_type -> aggregator.ListSecretsResp + 56, // 78: aggregator.Aggregator.UpdateSecret:output_type -> google.protobuf.BoolValue + 62, // [62:79] is the sub-list for method output_type + 45, // [45:62] is the sub-list for method input_type + 45, // [45:45] is the sub-list for extension type_name + 45, // [45:45] is the sub-list for extension extendee + 0, // [0:45] is the sub-list for field type_name } func init() { file_protobuf_avs_proto_init() } @@ -4615,7 +4987,31 @@ func file_protobuf_avs_proto_init() { } } file_protobuf_avs_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EventCondition_Matcher); i { + switch v := v.(*CreateOrUpdateSecretReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_avs_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListSecretsReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_avs_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListSecretsResp); i { case 0: return &v.state case 1: @@ -4627,7 +5023,7 @@ func file_protobuf_avs_proto_init() { } } file_protobuf_avs_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Execution_Step); i { + switch v := v.(*DeleteSecretReq); i { case 0: return &v.state case 1: @@ -4639,6 +5035,30 @@ func file_protobuf_avs_proto_init() { } } file_protobuf_avs_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EventCondition_Matcher); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_avs_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Execution_Step); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protobuf_avs_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListTasksResp_Item); i { case 0: return &v.state @@ -4650,6 +5070,18 @@ func file_protobuf_avs_proto_init() { return nil } } + file_protobuf_avs_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListSecretsResp_ResponseSecret); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_protobuf_avs_proto_msgTypes[5].OneofWrappers = []interface{}{ (*TaskTrigger_Manual)(nil), @@ -4683,7 +5115,7 @@ func file_protobuf_avs_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_protobuf_avs_proto_rawDesc, NumEnums: 5, - NumMessages: 45, + NumMessages: 50, NumExtensions: 0, NumServices: 1, }, diff --git a/protobuf/avs.proto b/protobuf/avs.proto index d1db6b46..107c240b 100644 --- a/protobuf/avs.proto +++ b/protobuf/avs.proto @@ -468,6 +468,49 @@ message UserTriggerTaskResp { ExecutionStatus status = 2; } +message CreateOrUpdateSecretReq { + // name of the secret. it should be [a-zA-Z0-9_]+ + string name = 1; + + // value can be any valid unicode string + // Secret is the only thing we can change in an update. workflow and org id cannot be change + string secret = 2; + + // A secret when define can be at these level + // - org: available to everything in the org. Currently this isn't supported yet. reserve for future use + // - user: available to all workflow of an user. This is the default level + // - workflow: available to a single workflow. To make a secret available to multiple workflow, either use org/user level or define them on other workflow. + string workflow_id = 3; + string org_id = 4; +} + +message ListSecretsReq { + string workflow_id = 1; +} + +message ListSecretsResp { + message ResponseSecret { + // when listing secret, we don't return its value, just secret and last update + string name = 1; + string scope = 2; + + string workflow_id = 4; + string org_id = 5; + } + repeated ResponseSecret items = 1; +} + +message DeleteSecretReq { + string name = 1; + + // Delete the secret belong to the specific workflow. Without its, we delete the one belong to user + string workflow_id = 2; + + // Delete the secret belong to the specific prg. Without its, we delete the one belong to user + string org_id = 3; +} + + service Aggregator { // Exchange for an Auth Key to authenticate in subsequent request rpc GetKey(GetKeyReq) returns (KeyResp) {}; @@ -489,4 +532,18 @@ service Aggregator { rpc CancelTask(IdReq) returns (google.protobuf.BoolValue) {}; rpc DeleteTask(IdReq) returns (google.protobuf.BoolValue) {}; rpc TriggerTask(UserTriggerTaskReq) returns (UserTriggerTaskResp) {}; + + // CreateSecret allow you to define a secret to be used in your tasks. The secret can be used with a special syntax of ${{secrets.name }}. + // You can decide whether to grant secret to a single workflow or many workflow, or all of your workflow + // By default, your secret is available across all of your tasks. + rpc CreateSecret(CreateOrUpdateSecretReq) returns (google.protobuf.BoolValue) {}; + rpc Delete(DeleteSecretReq) returns (google.protobuf.BoolValue) {}; + + // Return all secrets belong to this user. Currently we don't support any fine tune or filter yet. + // Only secret names and config data are returned. The secret value aren't returned. + rpc ListSecrets(ListSecretsReq) returns (ListSecretsResp) {}; + + // For simplicity, currently only the user who create the secrets can update its value, or update its permission. + // The current implementation is also limited, update is an override action, not an appending action. So when updating, you need to pass the whole payload + rpc UpdateSecret(CreateOrUpdateSecretReq) returns (google.protobuf.BoolValue) {}; } diff --git a/protobuf/avs_grpc.pb.go b/protobuf/avs_grpc.pb.go index 56f3b91a..63e649d5 100644 --- a/protobuf/avs_grpc.pb.go +++ b/protobuf/avs_grpc.pb.go @@ -39,6 +39,17 @@ type AggregatorClient interface { CancelTask(ctx context.Context, in *IdReq, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) DeleteTask(ctx context.Context, in *IdReq, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) TriggerTask(ctx context.Context, in *UserTriggerTaskReq, opts ...grpc.CallOption) (*UserTriggerTaskResp, error) + // CreateSecret allow you to define a secret to be used in your tasks. The secret can be used with a special syntax of ${{secrets.name }}. + // You can decide whether to grant secret to a single workflow or many workflow, or all of your workflow + // By default, your secret is available across all of your tasks. + CreateSecret(ctx context.Context, in *CreateOrUpdateSecretReq, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) + Delete(ctx context.Context, in *DeleteSecretReq, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) + // Return all secrets belong to this user. Currently we don't support any fine tune or filter yet. + // Only secret names and config data are returned. The secret value aren't returned. + ListSecrets(ctx context.Context, in *ListSecretsReq, opts ...grpc.CallOption) (*ListSecretsResp, error) + // For simplicity, currently only the user who create the secrets can update its value, or update its permission. + // The current implementation is also limited, update is an override action, not an appending action. So when updating, you need to pass the whole payload + UpdateSecret(ctx context.Context, in *CreateOrUpdateSecretReq, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) } type aggregatorClient struct { @@ -166,6 +177,42 @@ func (c *aggregatorClient) TriggerTask(ctx context.Context, in *UserTriggerTaskR return out, nil } +func (c *aggregatorClient) CreateSecret(ctx context.Context, in *CreateOrUpdateSecretReq, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { + out := new(wrapperspb.BoolValue) + err := c.cc.Invoke(ctx, "/aggregator.Aggregator/CreateSecret", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *aggregatorClient) Delete(ctx context.Context, in *DeleteSecretReq, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { + out := new(wrapperspb.BoolValue) + err := c.cc.Invoke(ctx, "/aggregator.Aggregator/Delete", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *aggregatorClient) ListSecrets(ctx context.Context, in *ListSecretsReq, opts ...grpc.CallOption) (*ListSecretsResp, error) { + out := new(ListSecretsResp) + err := c.cc.Invoke(ctx, "/aggregator.Aggregator/ListSecrets", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *aggregatorClient) UpdateSecret(ctx context.Context, in *CreateOrUpdateSecretReq, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { + out := new(wrapperspb.BoolValue) + err := c.cc.Invoke(ctx, "/aggregator.Aggregator/UpdateSecret", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // AggregatorServer is the server API for Aggregator service. // All implementations must embed UnimplementedAggregatorServer // for forward compatibility @@ -186,6 +233,17 @@ type AggregatorServer interface { CancelTask(context.Context, *IdReq) (*wrapperspb.BoolValue, error) DeleteTask(context.Context, *IdReq) (*wrapperspb.BoolValue, error) TriggerTask(context.Context, *UserTriggerTaskReq) (*UserTriggerTaskResp, error) + // CreateSecret allow you to define a secret to be used in your tasks. The secret can be used with a special syntax of ${{secrets.name }}. + // You can decide whether to grant secret to a single workflow or many workflow, or all of your workflow + // By default, your secret is available across all of your tasks. + CreateSecret(context.Context, *CreateOrUpdateSecretReq) (*wrapperspb.BoolValue, error) + Delete(context.Context, *DeleteSecretReq) (*wrapperspb.BoolValue, error) + // Return all secrets belong to this user. Currently we don't support any fine tune or filter yet. + // Only secret names and config data are returned. The secret value aren't returned. + ListSecrets(context.Context, *ListSecretsReq) (*ListSecretsResp, error) + // For simplicity, currently only the user who create the secrets can update its value, or update its permission. + // The current implementation is also limited, update is an override action, not an appending action. So when updating, you need to pass the whole payload + UpdateSecret(context.Context, *CreateOrUpdateSecretReq) (*wrapperspb.BoolValue, error) mustEmbedUnimplementedAggregatorServer() } @@ -232,6 +290,18 @@ func (UnimplementedAggregatorServer) DeleteTask(context.Context, *IdReq) (*wrapp func (UnimplementedAggregatorServer) TriggerTask(context.Context, *UserTriggerTaskReq) (*UserTriggerTaskResp, error) { return nil, status.Errorf(codes.Unimplemented, "method TriggerTask not implemented") } +func (UnimplementedAggregatorServer) CreateSecret(context.Context, *CreateOrUpdateSecretReq) (*wrapperspb.BoolValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateSecret not implemented") +} +func (UnimplementedAggregatorServer) Delete(context.Context, *DeleteSecretReq) (*wrapperspb.BoolValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") +} +func (UnimplementedAggregatorServer) ListSecrets(context.Context, *ListSecretsReq) (*ListSecretsResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListSecrets not implemented") +} +func (UnimplementedAggregatorServer) UpdateSecret(context.Context, *CreateOrUpdateSecretReq) (*wrapperspb.BoolValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateSecret not implemented") +} func (UnimplementedAggregatorServer) mustEmbedUnimplementedAggregatorServer() {} // UnsafeAggregatorServer may be embedded to opt out of forward compatibility for this service. @@ -479,6 +549,78 @@ func _Aggregator_TriggerTask_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } +func _Aggregator_CreateSecret_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateOrUpdateSecretReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AggregatorServer).CreateSecret(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/aggregator.Aggregator/CreateSecret", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AggregatorServer).CreateSecret(ctx, req.(*CreateOrUpdateSecretReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Aggregator_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteSecretReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AggregatorServer).Delete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/aggregator.Aggregator/Delete", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AggregatorServer).Delete(ctx, req.(*DeleteSecretReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Aggregator_ListSecrets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListSecretsReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AggregatorServer).ListSecrets(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/aggregator.Aggregator/ListSecrets", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AggregatorServer).ListSecrets(ctx, req.(*ListSecretsReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Aggregator_UpdateSecret_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateOrUpdateSecretReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AggregatorServer).UpdateSecret(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/aggregator.Aggregator/UpdateSecret", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AggregatorServer).UpdateSecret(ctx, req.(*CreateOrUpdateSecretReq)) + } + return interceptor(ctx, in, info, handler) +} + // Aggregator_ServiceDesc is the grpc.ServiceDesc for Aggregator service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -538,6 +680,22 @@ var Aggregator_ServiceDesc = grpc.ServiceDesc{ MethodName: "TriggerTask", Handler: _Aggregator_TriggerTask_Handler, }, + { + MethodName: "CreateSecret", + Handler: _Aggregator_CreateSecret_Handler, + }, + { + MethodName: "Delete", + Handler: _Aggregator_Delete_Handler, + }, + { + MethodName: "ListSecrets", + Handler: _Aggregator_ListSecrets_Handler, + }, + { + MethodName: "UpdateSecret", + Handler: _Aggregator_UpdateSecret_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "protobuf/avs.proto",