diff --git a/app/cli/api/attestation/v1/crafting_state.pb.go b/app/cli/api/attestation/v1/crafting_state.pb.go index a62027582..e08e4832f 100644 --- a/app/cli/api/attestation/v1/crafting_state.pb.go +++ b/app/cli/api/attestation/v1/crafting_state.pb.go @@ -3,8 +3,7 @@ // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// +// You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software @@ -47,6 +46,8 @@ type Attestation struct { FinishedAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=finished_at,json=finishedAt,proto3" json:"finished_at,omitempty"` Workflow *WorkflowMetadata `protobuf:"bytes,3,opt,name=workflow,proto3" json:"workflow,omitempty"` Materials map[string]*Attestation_Material `protobuf:"bytes,4,rep,name=materials,proto3" json:"materials,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Annotations for the attestation + Annotations map[string]string `protobuf:"bytes,5,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // List of env variables EnvVars map[string]string `protobuf:"bytes,6,rep,name=env_vars,json=envVars,proto3" json:"env_vars,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` RunnerUrl string `protobuf:"bytes,7,opt,name=runner_url,json=runnerUrl,proto3" json:"runner_url,omitempty"` @@ -113,6 +114,13 @@ func (x *Attestation) GetMaterials() map[string]*Attestation_Material { return nil } +func (x *Attestation) GetAnnotations() map[string]string { + if x != nil { + return x.Annotations + } + return nil +} + func (x *Attestation) GetEnvVars() map[string]string { if x != nil { return x.EnvVars @@ -310,7 +318,7 @@ type Attestation_Material struct { func (x *Attestation_Material) Reset() { *x = Attestation_Material{} if protoimpl.UnsafeEnabled { - mi := &file_attestation_v1_crafting_state_proto_msgTypes[4] + mi := &file_attestation_v1_crafting_state_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -323,7 +331,7 @@ func (x *Attestation_Material) String() string { func (*Attestation_Material) ProtoMessage() {} func (x *Attestation_Material) ProtoReflect() protoreflect.Message { - mi := &file_attestation_v1_crafting_state_proto_msgTypes[4] + mi := &file_attestation_v1_crafting_state_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -336,7 +344,7 @@ func (x *Attestation_Material) ProtoReflect() protoreflect.Message { // Deprecated: Use Attestation_Material.ProtoReflect.Descriptor instead. func (*Attestation_Material) Descriptor() ([]byte, []int) { - return file_attestation_v1_crafting_state_proto_rawDescGZIP(), []int{0, 1} + return file_attestation_v1_crafting_state_proto_rawDescGZIP(), []int{0, 2} } func (m *Attestation_Material) GetM() isAttestation_Material_M { @@ -436,7 +444,7 @@ type Attestation_Material_KeyVal struct { func (x *Attestation_Material_KeyVal) Reset() { *x = Attestation_Material_KeyVal{} if protoimpl.UnsafeEnabled { - mi := &file_attestation_v1_crafting_state_proto_msgTypes[7] + mi := &file_attestation_v1_crafting_state_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -449,7 +457,7 @@ func (x *Attestation_Material_KeyVal) String() string { func (*Attestation_Material_KeyVal) ProtoMessage() {} func (x *Attestation_Material_KeyVal) ProtoReflect() protoreflect.Message { - mi := &file_attestation_v1_crafting_state_proto_msgTypes[7] + mi := &file_attestation_v1_crafting_state_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -462,7 +470,7 @@ func (x *Attestation_Material_KeyVal) ProtoReflect() protoreflect.Message { // Deprecated: Use Attestation_Material_KeyVal.ProtoReflect.Descriptor instead. func (*Attestation_Material_KeyVal) Descriptor() ([]byte, []int) { - return file_attestation_v1_crafting_state_proto_rawDescGZIP(), []int{0, 1, 1} + return file_attestation_v1_crafting_state_proto_rawDescGZIP(), []int{0, 2, 1} } func (x *Attestation_Material_KeyVal) GetId() string { @@ -493,7 +501,7 @@ type Attestation_Material_ContainerImage struct { func (x *Attestation_Material_ContainerImage) Reset() { *x = Attestation_Material_ContainerImage{} if protoimpl.UnsafeEnabled { - mi := &file_attestation_v1_crafting_state_proto_msgTypes[8] + mi := &file_attestation_v1_crafting_state_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -506,7 +514,7 @@ func (x *Attestation_Material_ContainerImage) String() string { func (*Attestation_Material_ContainerImage) ProtoMessage() {} func (x *Attestation_Material_ContainerImage) ProtoReflect() protoreflect.Message { - mi := &file_attestation_v1_crafting_state_proto_msgTypes[8] + mi := &file_attestation_v1_crafting_state_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -519,7 +527,7 @@ func (x *Attestation_Material_ContainerImage) ProtoReflect() protoreflect.Messag // Deprecated: Use Attestation_Material_ContainerImage.ProtoReflect.Descriptor instead. func (*Attestation_Material_ContainerImage) Descriptor() ([]byte, []int) { - return file_attestation_v1_crafting_state_proto_rawDescGZIP(), []int{0, 1, 2} + return file_attestation_v1_crafting_state_proto_rawDescGZIP(), []int{0, 2, 2} } func (x *Attestation_Material_ContainerImage) GetId() string { @@ -571,7 +579,7 @@ type Attestation_Material_Artifact struct { func (x *Attestation_Material_Artifact) Reset() { *x = Attestation_Material_Artifact{} if protoimpl.UnsafeEnabled { - mi := &file_attestation_v1_crafting_state_proto_msgTypes[9] + mi := &file_attestation_v1_crafting_state_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -584,7 +592,7 @@ func (x *Attestation_Material_Artifact) String() string { func (*Attestation_Material_Artifact) ProtoMessage() {} func (x *Attestation_Material_Artifact) ProtoReflect() protoreflect.Message { - mi := &file_attestation_v1_crafting_state_proto_msgTypes[9] + mi := &file_attestation_v1_crafting_state_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -597,7 +605,7 @@ func (x *Attestation_Material_Artifact) ProtoReflect() protoreflect.Message { // Deprecated: Use Attestation_Material_Artifact.ProtoReflect.Descriptor instead. func (*Attestation_Material_Artifact) Descriptor() ([]byte, []int) { - return file_attestation_v1_crafting_state_proto_rawDescGZIP(), []int{0, 1, 3} + return file_attestation_v1_crafting_state_proto_rawDescGZIP(), []int{0, 2, 3} } func (x *Attestation_Material_Artifact) GetId() string { @@ -647,7 +655,7 @@ var file_attestation_v1_crafting_state_proto_rawDesc = []byte{ 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf8, 0x0c, 0x0a, 0x0b, 0x41, + 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x96, 0x0e, 0x0a, 0x0b, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4b, 0x0a, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, @@ -666,122 +674,132 @@ var file_attestation_v1_crafting_state_proto_rawDesc = []byte{ 0x2a, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x6d, 0x61, 0x74, - 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x43, 0x0a, 0x08, 0x65, 0x6e, 0x76, 0x5f, 0x76, 0x61, - 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, - 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x56, 0x0a, 0x0b, 0x72, 0x75, - 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x35, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, - 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x75, 0x6e, 0x6e, - 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x54, 0x79, - 0x70, 0x65, 0x1a, 0x62, 0x0a, 0x0e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0xf0, 0x07, 0x0a, 0x08, 0x4d, 0x61, 0x74, 0x65, 0x72, - 0x69, 0x61, 0x6c, 0x12, 0x45, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, - 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x5e, 0x0a, 0x0f, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x5c, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x61, 0x74, + 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, + 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x0c, 0xfa, 0x42, 0x09, 0x9a, 0x01, + 0x06, 0x2a, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x08, 0x65, 0x6e, 0x76, 0x5f, 0x76, 0x61, 0x72, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x07, 0x65, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x75, 0x6e, + 0x6e, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, + 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x56, 0x0a, 0x0b, 0x72, 0x75, 0x6e, 0x6e, + 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, + 0x1a, 0x62, 0x0a, 0x0e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x4b, 0x0a, 0x08, 0x61, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x61, - 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, - 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, - 0x61, 0x6c, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x48, 0x00, 0x52, 0x08, 0x61, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x61, 0x64, 0x64, 0x65, 0x64, - 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x61, 0x64, 0x64, 0x65, 0x64, 0x41, 0x74, 0x12, 0x5e, - 0x0a, 0x0d, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x61, 0x66, - 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, - 0x69, 0x61, 0x6c, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x0c, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, - 0x0a, 0x0f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x61, - 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, - 0x64, 0x54, 0x6f, 0x43, 0x61, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, - 0x5f, 0x63, 0x61, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x6e, 0x6c, 0x69, - 0x6e, 0x65, 0x43, 0x61, 0x73, 0x12, 0x65, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x61, 0x74, 0x74, + 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x1a, 0xf0, 0x07, 0x0a, 0x08, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, + 0x6c, 0x12, 0x45, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, + 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x48, 0x00, + 0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x5e, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x33, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, + 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x4b, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, - 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x42, 0x0c, 0xfa, 0x42, 0x09, 0x9a, 0x01, 0x06, 0x2a, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, - 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, 0x0a, 0x10, - 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x40, 0x0a, 0x06, - 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x1d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, - 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x86, - 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, - 0x65, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, - 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, - 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, - 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, - 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, - 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x1a, 0x9a, 0x01, 0x0a, 0x08, 0x41, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, - 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x64, 0x69, - 0x67, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, - 0x02, 0x10, 0x01, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, - 0x73, 0x5f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x69, 0x73, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x42, 0x03, 0x0a, 0x01, 0x6d, 0x1a, 0x3a, 0x0a, 0x0c, 0x45, 0x6e, 0x76, - 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xaf, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, - 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x46, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, - 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x52, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, - 0x3d, 0x0a, 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, - 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x22, 0xe1, 0x01, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, - 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x65, 0x61, 0x6d, 0x12, 0x28, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, - 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x49, - 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x75, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0f, 0x73, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x73, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x3f, 0x5a, 0x3d, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, - 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, - 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6c, 0x69, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x74, - 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x48, 0x00, 0x52, 0x08, 0x61, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x07, 0x61, 0x64, 0x64, 0x65, 0x64, 0x41, 0x74, 0x12, 0x5e, 0x0a, 0x0d, + 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, + 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, + 0x6c, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, + 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x0f, + 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x61, 0x73, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x54, + 0x6f, 0x43, 0x61, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, + 0x61, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x43, 0x61, 0x73, 0x12, 0x65, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x41, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, + 0x0c, 0xfa, 0x42, 0x09, 0x9a, 0x01, 0x06, 0x2a, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x61, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x40, 0x0a, 0x06, 0x4b, 0x65, + 0x79, 0x56, 0x61, 0x6c, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, + 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x86, 0x01, 0x0a, + 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, + 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, + 0x72, 0x02, 0x10, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, + 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x1a, 0x9a, 0x01, 0x0a, 0x08, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, + 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, + 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, + 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, + 0x01, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, + 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, + 0x73, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x42, 0x03, 0x0a, 0x01, 0x6d, 0x1a, 0x3a, 0x0a, 0x0c, 0x45, 0x6e, 0x76, 0x56, 0x61, + 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0xaf, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x46, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x52, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x3d, 0x0a, + 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, + 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, + 0x72, 0x79, 0x52, 0x75, 0x6e, 0x22, 0xe1, 0x01, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, + 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x74, 0x65, 0x61, 0x6d, 0x12, 0x28, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, + 0x02, 0x10, 0x01, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x12, + 0x26, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x75, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0f, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x3f, 0x5a, 0x3d, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, + 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, + 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6c, 0x69, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x74, 0x74, 0x65, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -796,44 +814,46 @@ func file_attestation_v1_crafting_state_proto_rawDescGZIP() []byte { return file_attestation_v1_crafting_state_proto_rawDescData } -var file_attestation_v1_crafting_state_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_attestation_v1_crafting_state_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_attestation_v1_crafting_state_proto_goTypes = []interface{}{ (*Attestation)(nil), // 0: attestation.v1.Attestation (*CraftingState)(nil), // 1: attestation.v1.CraftingState (*WorkflowMetadata)(nil), // 2: attestation.v1.WorkflowMetadata nil, // 3: attestation.v1.Attestation.MaterialsEntry - (*Attestation_Material)(nil), // 4: attestation.v1.Attestation.Material - nil, // 5: attestation.v1.Attestation.EnvVarsEntry - nil, // 6: attestation.v1.Attestation.Material.AnnotationsEntry - (*Attestation_Material_KeyVal)(nil), // 7: attestation.v1.Attestation.Material.KeyVal - (*Attestation_Material_ContainerImage)(nil), // 8: attestation.v1.Attestation.Material.ContainerImage - (*Attestation_Material_Artifact)(nil), // 9: attestation.v1.Attestation.Material.Artifact - (*timestamppb.Timestamp)(nil), // 10: google.protobuf.Timestamp - (v1.CraftingSchema_Runner_RunnerType)(0), // 11: workflowcontract.v1.CraftingSchema.Runner.RunnerType - (*v1.CraftingSchema)(nil), // 12: workflowcontract.v1.CraftingSchema - (v1.CraftingSchema_Material_MaterialType)(0), // 13: workflowcontract.v1.CraftingSchema.Material.MaterialType + nil, // 4: attestation.v1.Attestation.AnnotationsEntry + (*Attestation_Material)(nil), // 5: attestation.v1.Attestation.Material + nil, // 6: attestation.v1.Attestation.EnvVarsEntry + nil, // 7: attestation.v1.Attestation.Material.AnnotationsEntry + (*Attestation_Material_KeyVal)(nil), // 8: attestation.v1.Attestation.Material.KeyVal + (*Attestation_Material_ContainerImage)(nil), // 9: attestation.v1.Attestation.Material.ContainerImage + (*Attestation_Material_Artifact)(nil), // 10: attestation.v1.Attestation.Material.Artifact + (*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp + (v1.CraftingSchema_Runner_RunnerType)(0), // 12: workflowcontract.v1.CraftingSchema.Runner.RunnerType + (*v1.CraftingSchema)(nil), // 13: workflowcontract.v1.CraftingSchema + (v1.CraftingSchema_Material_MaterialType)(0), // 14: workflowcontract.v1.CraftingSchema.Material.MaterialType } var file_attestation_v1_crafting_state_proto_depIdxs = []int32{ - 10, // 0: attestation.v1.Attestation.initialized_at:type_name -> google.protobuf.Timestamp - 10, // 1: attestation.v1.Attestation.finished_at:type_name -> google.protobuf.Timestamp + 11, // 0: attestation.v1.Attestation.initialized_at:type_name -> google.protobuf.Timestamp + 11, // 1: attestation.v1.Attestation.finished_at:type_name -> google.protobuf.Timestamp 2, // 2: attestation.v1.Attestation.workflow:type_name -> attestation.v1.WorkflowMetadata 3, // 3: attestation.v1.Attestation.materials:type_name -> attestation.v1.Attestation.MaterialsEntry - 5, // 4: attestation.v1.Attestation.env_vars:type_name -> attestation.v1.Attestation.EnvVarsEntry - 11, // 5: attestation.v1.Attestation.runner_type:type_name -> workflowcontract.v1.CraftingSchema.Runner.RunnerType - 12, // 6: attestation.v1.CraftingState.input_schema:type_name -> workflowcontract.v1.CraftingSchema - 0, // 7: attestation.v1.CraftingState.attestation:type_name -> attestation.v1.Attestation - 4, // 8: attestation.v1.Attestation.MaterialsEntry.value:type_name -> attestation.v1.Attestation.Material - 7, // 9: attestation.v1.Attestation.Material.string:type_name -> attestation.v1.Attestation.Material.KeyVal - 8, // 10: attestation.v1.Attestation.Material.container_image:type_name -> attestation.v1.Attestation.Material.ContainerImage - 9, // 11: attestation.v1.Attestation.Material.artifact:type_name -> attestation.v1.Attestation.Material.Artifact - 10, // 12: attestation.v1.Attestation.Material.added_at:type_name -> google.protobuf.Timestamp - 13, // 13: attestation.v1.Attestation.Material.material_type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType - 6, // 14: attestation.v1.Attestation.Material.annotations:type_name -> attestation.v1.Attestation.Material.AnnotationsEntry - 15, // [15:15] is the sub-list for method output_type - 15, // [15:15] is the sub-list for method input_type - 15, // [15:15] is the sub-list for extension type_name - 15, // [15:15] is the sub-list for extension extendee - 0, // [0:15] is the sub-list for field type_name + 4, // 4: attestation.v1.Attestation.annotations:type_name -> attestation.v1.Attestation.AnnotationsEntry + 6, // 5: attestation.v1.Attestation.env_vars:type_name -> attestation.v1.Attestation.EnvVarsEntry + 12, // 6: attestation.v1.Attestation.runner_type:type_name -> workflowcontract.v1.CraftingSchema.Runner.RunnerType + 13, // 7: attestation.v1.CraftingState.input_schema:type_name -> workflowcontract.v1.CraftingSchema + 0, // 8: attestation.v1.CraftingState.attestation:type_name -> attestation.v1.Attestation + 5, // 9: attestation.v1.Attestation.MaterialsEntry.value:type_name -> attestation.v1.Attestation.Material + 8, // 10: attestation.v1.Attestation.Material.string:type_name -> attestation.v1.Attestation.Material.KeyVal + 9, // 11: attestation.v1.Attestation.Material.container_image:type_name -> attestation.v1.Attestation.Material.ContainerImage + 10, // 12: attestation.v1.Attestation.Material.artifact:type_name -> attestation.v1.Attestation.Material.Artifact + 11, // 13: attestation.v1.Attestation.Material.added_at:type_name -> google.protobuf.Timestamp + 14, // 14: attestation.v1.Attestation.Material.material_type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType + 7, // 15: attestation.v1.Attestation.Material.annotations:type_name -> attestation.v1.Attestation.Material.AnnotationsEntry + 16, // [16:16] is the sub-list for method output_type + 16, // [16:16] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name } func init() { file_attestation_v1_crafting_state_proto_init() } @@ -878,7 +898,7 @@ func file_attestation_v1_crafting_state_proto_init() { return nil } } - file_attestation_v1_crafting_state_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_attestation_v1_crafting_state_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Attestation_Material); i { case 0: return &v.state @@ -890,7 +910,7 @@ func file_attestation_v1_crafting_state_proto_init() { return nil } } - file_attestation_v1_crafting_state_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_attestation_v1_crafting_state_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Attestation_Material_KeyVal); i { case 0: return &v.state @@ -902,7 +922,7 @@ func file_attestation_v1_crafting_state_proto_init() { return nil } } - file_attestation_v1_crafting_state_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_attestation_v1_crafting_state_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Attestation_Material_ContainerImage); i { case 0: return &v.state @@ -914,7 +934,7 @@ func file_attestation_v1_crafting_state_proto_init() { return nil } } - file_attestation_v1_crafting_state_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_attestation_v1_crafting_state_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Attestation_Material_Artifact); i { case 0: return &v.state @@ -927,7 +947,7 @@ func file_attestation_v1_crafting_state_proto_init() { } } } - file_attestation_v1_crafting_state_proto_msgTypes[4].OneofWrappers = []interface{}{ + file_attestation_v1_crafting_state_proto_msgTypes[5].OneofWrappers = []interface{}{ (*Attestation_Material_String_)(nil), (*Attestation_Material_ContainerImage_)(nil), (*Attestation_Material_Artifact_)(nil), @@ -938,7 +958,7 @@ func file_attestation_v1_crafting_state_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_attestation_v1_crafting_state_proto_rawDesc, NumEnums: 0, - NumMessages: 10, + NumMessages: 11, NumExtensions: 0, NumServices: 0, }, diff --git a/app/cli/api/attestation/v1/crafting_state.pb.validate.go b/app/cli/api/attestation/v1/crafting_state.pb.validate.go index 4ee7912d6..e8dbb71cb 100644 --- a/app/cli/api/attestation/v1/crafting_state.pb.validate.go +++ b/app/cli/api/attestation/v1/crafting_state.pb.validate.go @@ -187,6 +187,34 @@ func (m *Attestation) validate(all bool) error { } } + { + sorted_keys := make([]string, len(m.GetAnnotations())) + i := 0 + for key := range m.GetAnnotations() { + sorted_keys[i] = key + i++ + } + sort.Slice(sorted_keys, func(i, j int) bool { return sorted_keys[i] < sorted_keys[j] }) + for _, key := range sorted_keys { + val := m.GetAnnotations()[key] + _ = val + + // no validation rules for Annotations[key] + + if utf8.RuneCountInString(val) < 1 { + err := AttestationValidationError{ + field: fmt.Sprintf("Annotations[%v]", key), + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + } + // no validation rules for EnvVars // no validation rules for RunnerUrl diff --git a/app/cli/api/attestation/v1/crafting_state.proto b/app/cli/api/attestation/v1/crafting_state.proto index 6165bb0c0..ade44e949 100644 --- a/app/cli/api/attestation/v1/crafting_state.proto +++ b/app/cli/api/attestation/v1/crafting_state.proto @@ -30,6 +30,8 @@ message Attestation { WorkflowMetadata workflow = 3 [(validate.rules).message.required = true]; map materials = 4; + // Annotations for the attestation + map annotations = 5 [(validate.rules).map.values.string.min_len = 1]; message Material { oneof m { diff --git a/app/cli/cmd/attestation.go b/app/cli/cmd/attestation.go index 6ccafd5d6..e2bd4cf07 100644 --- a/app/cli/cmd/attestation.go +++ b/app/cli/cmd/attestation.go @@ -18,6 +18,7 @@ package cmd import ( "fmt" "os" + "strings" "github.com/spf13/cobra" ) @@ -49,3 +50,18 @@ func newAttestationCmd() *cobra.Command { return cmd } + +// extractAnnotations extracts the annotations from the flag and returns a map +// the expected input format is key=value +func extractAnnotations(annotationsFlag []string) (map[string]string, error) { + var annotations = make(map[string]string) + for _, annotation := range annotationsFlag { + kv := strings.Split(annotation, "=") + if len(kv) != 2 { + return nil, fmt.Errorf("invalid annotation %q, the format must be key=value", annotation) + } + annotations[kv[0]] = kv[1] + } + + return annotations, nil +} diff --git a/app/cli/cmd/attestation_add.go b/app/cli/cmd/attestation_add.go index e6ec1459b..032b857a2 100644 --- a/app/cli/cmd/attestation_add.go +++ b/app/cli/cmd/attestation_add.go @@ -17,8 +17,6 @@ package cmd import ( "errors" - "fmt" - "strings" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -48,17 +46,12 @@ func newAttestationAddCmd() *cobra.Command { ) // Extract annotations - var annotations = make(map[string]string) - for _, annotation := range annotationsFlag { - kv := strings.SplitN(annotation, "=", 2) - if len(kv) != 2 { - return fmt.Errorf("invalid annotation %q, the format must be key=value", annotation) - } - annotations[kv[0]] = kv[1] + annotations, err := extractAnnotations(annotationsFlag) + if err != nil { + return err } - err := a.Run(name, value, annotations) - if err != nil { + if err := a.Run(name, value, annotations); err != nil { if errors.Is(err, action.ErrAttestationNotInitialized) { return err } diff --git a/app/cli/cmd/attestation_push.go b/app/cli/cmd/attestation_push.go index 899e8408b..eee0758ee 100644 --- a/app/cli/cmd/attestation_push.go +++ b/app/cli/cmd/attestation_push.go @@ -25,10 +25,11 @@ import ( func newAttestationPushCmd() *cobra.Command { var pkPath string + var annotationsFlag []string cmd := &cobra.Command{ Use: "push", Short: "generate and push the attestation to the control plane", - Example: ` chainloop attestation push --key | --token [robot-account-token] + Example: ` chainloop attestation push --key | --token [robot-account-token] --annotation key=value,key2=val2 # sign the resulting attestation using a cosign key present in the filesystem and stdin for the passphrase # NOTE that the --token flag can be replaced by having the CHAINLOOP_ROBOT_ACCOUNT env variable @@ -39,7 +40,12 @@ func newAttestationPushCmd() *cobra.Command { # The passphrase can be retrieved from a well-known environment variable export CHAINLOOP_SIGNING_PASSWORD="my cosign key passphrase" - chainloop attestation push --key cosign.key`, + chainloop attestation push --key cosign.key + + # You can provide values for the annotations that have previously defined in the contract for example + chainloop attestation push --annotation key=value --annotation key2=value2 + # Or alternatively + chainloop attestation push --annotation key=value,key2=value2`, Annotations: map[string]string{ useWorkflowRobotAccount: "true", }, @@ -59,7 +65,12 @@ func newAttestationPushCmd() *cobra.Command { ActionsOpts: actionOpts, KeyPath: pkPath, CLIVersion: info.Version, CLIDigest: info.Digest, }) - res, err := a.Run() + annotations, err := extractAnnotations(annotationsFlag) + if err != nil { + return err + } + + res, err := a.Run(annotations) if err != nil { if errors.Is(err, action.ErrAttestationNotInitialized) { return err @@ -73,6 +84,7 @@ func newAttestationPushCmd() *cobra.Command { } cmd.Flags().StringVarP(&pkPath, "key", "k", "", "reference (path or env variable name) to the cosign private key that will be used to sign the attestation") + cmd.Flags().StringSliceVar(&annotationsFlag, "annotation", nil, "additional annotation in the format of key=value") return cmd } diff --git a/app/cli/cmd/attestation_status.go b/app/cli/cmd/attestation_status.go index a62867814..bcd284727 100644 --- a/app/cli/cmd/attestation_status.go +++ b/app/cli/cmd/attestation_status.go @@ -69,6 +69,18 @@ func attestationStatusTableOutput(status *action.AttestationStatusResult) error gt.AppendRow(table.Row{"Runner Type", status.RunnerContext.RunnerType}) gt.AppendRow(table.Row{"Runner URL", status.RunnerContext.JobURL}) } + + if len(status.Annotations) > 0 { + gt.AppendRow(table.Row{"Annotations", "------"}) + for _, a := range status.Annotations { + value := a.Value + if value == "" { + value = "[NOT SET]" + } + gt.AppendRow(table.Row{"", fmt.Sprintf("%s: %s", a.Name, value)}) + } + } + gt.Render() if err := materialsTable(status); err != nil { @@ -149,7 +161,12 @@ func materialsTable(status *action.AttestationStatusResult) error { if len(m.Annotations) > 0 { mt.AppendRow(table.Row{"Annotations", "------"}) for _, a := range m.Annotations { - mt.AppendRow(table.Row{"", fmt.Sprintf("%s: %s", a.Name, a.Value)}) + value := a.Value + if value == "" { + value = "[NOT SET]" + } + + mt.AppendRow(table.Row{"", fmt.Sprintf("%s: %s", a.Name, value)}) } } diff --git a/app/cli/cmd/attestation_test.go b/app/cli/cmd/attestation_test.go new file mode 100644 index 000000000..883ba7b29 --- /dev/null +++ b/app/cli/cmd/attestation_test.go @@ -0,0 +1,79 @@ +// +// Copyright 2023 The Chainloop Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestExtractAnnotations(t *testing.T) { + testCases := []struct { + input []string + want map[string]string + wantErr bool + }{ + { + input: []string{ + "foo=bar", + "baz=qux", + }, + want: map[string]string{ + "foo": "bar", + "baz": "qux", + }, + wantErr: false, + }, + { + input: []string{ + "foo=bar", + "baz", + }, + wantErr: true, + }, + { + input: []string{ + "foo=bar", + "baz=qux", + "foo=bar", + }, + want: map[string]string{ + "foo": "bar", + "baz": "qux", + }, + wantErr: false, + }, + { + input: []string{ + "foo=bar", + "baz=qux=qux", + }, + wantErr: true, + }, + } + + for _, tc := range testCases { + got, err := extractAnnotations(tc.input) + if tc.wantErr { + assert.Error(t, err) + continue + } + + assert.NoError(t, err) + assert.Equal(t, tc.want, got) + } +} diff --git a/app/cli/internal/action/attestation_push.go b/app/cli/internal/action/attestation_push.go index 8f0a3cbb4..52ca54c0b 100644 --- a/app/cli/internal/action/attestation_push.go +++ b/app/cli/internal/action/attestation_push.go @@ -18,6 +18,7 @@ package action import ( "context" "encoding/json" + "fmt" pb "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1" "github.com/chainloop-dev/chainloop/internal/attestation/crafter" @@ -48,7 +49,7 @@ func NewAttestationPush(cfg *AttestationPushOpts) *AttestationPush { } // TODO: Return defined type -func (action *AttestationPush) Run() (interface{}, error) { +func (action *AttestationPush) Run(runtimeAnnotations map[string]string) (interface{}, error) { if initialized := action.c.AlreadyInitialized(); !initialized { return nil, ErrAttestationNotInitialized } @@ -58,6 +59,44 @@ func (action *AttestationPush) Run() (interface{}, error) { return nil, err } + // Annotations + craftedAnnotations := make(map[string]string, 0) + // 1 - Set annotations that come from the contract + for _, v := range action.c.CraftingState.InputSchema.GetAnnotations() { + craftedAnnotations[v.Name] = v.Value + } + + // 2 - Populate annotation values from the ones provided at runtime + // a) we do not allow overriding values that come from the contract + // b) we do not allow adding annotations that are not defined in the contract + for kr, vr := range runtimeAnnotations { + // If the annotation is not defined in the material we fail + if v, found := craftedAnnotations[kr]; !found { + return nil, fmt.Errorf("annotation %q not found", kr) + } else if v == "" { + // Set it only if it's not set + craftedAnnotations[kr] = vr + } else { + // NOTE: we do not allow overriding values that come from the contract + action.Logger.Info().Str("annotation", kr).Msg("annotation can't be changed, skipping") + } + } + + // Make sure all the annotation values are now set + // This is in fact validated below but by manually checking we can provide a better error message + for k, v := range craftedAnnotations { + var missingAnnotations []string + if v == "" { + missingAnnotations = append(missingAnnotations, k) + } + + if len(missingAnnotations) > 0 { + return nil, fmt.Errorf("annotations %q required", missingAnnotations) + } + } + // Set the annotations + action.c.CraftingState.Attestation.Annotations = craftedAnnotations + if err := action.c.ValidateAttestation(); err != nil { return nil, err } diff --git a/app/cli/internal/action/attestation_status.go b/app/cli/internal/action/attestation_status.go index d771d5a16..130680bd7 100644 --- a/app/cli/internal/action/attestation_status.go +++ b/app/cli/internal/action/attestation_status.go @@ -40,6 +40,7 @@ type AttestationStatusResult struct { EnvVars map[string]string RunnerContext *AttestationResultRunnerContext DryRun bool + Annotations []*Annotation } type AttestationResultRunnerContext struct { @@ -89,6 +90,7 @@ func (action *AttestationStatus) Run() (*AttestationStatusResult, error) { }, InitializedAt: toTimePtr(att.InitializedAt.AsTime()), DryRun: c.CraftingState.DryRun, + Annotations: pbAnnotationsToAction(c.CraftingState.InputSchema.GetAnnotations()), } // Materials diff --git a/app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts b/app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts index 71df319e6..b961385bd 100644 --- a/app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts +++ b/app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts @@ -42,13 +42,9 @@ export interface FileDescriptorProto { sourceCodeInfo?: SourceCodeInfo; /** * The syntax of the proto file. - * The supported values are "proto2", "proto3", and "editions". - * - * If `edition` is present, this value must be "editions". + * The supported values are "proto2" and "proto3". */ syntax: string; - /** The edition of the proto file, which is an opaque string. */ - edition: string; } /** Describes a message type. */ @@ -623,10 +619,6 @@ export interface MessageOptions { */ deprecated: boolean; /** - * NOTE: Do not set the option in .proto files. Always use the maps syntax - * instead. The option should only be implicitly set by the proto compiler - * parser. - * * Whether the message is an automatically generated map entry type for the * maps field. * @@ -644,23 +636,12 @@ export interface MessageOptions { * use a native map in the target language to hold the keys and values. * The reflection APIs in such implementations still need to work as * if the field is a repeated message field. - */ - mapEntry: boolean; - /** - * Enable the legacy handling of JSON field name conflicts. This lowercases - * and strips underscored from the fields before comparison in proto3 only. - * The new behavior takes `json_name` into account and applies to proto2 as - * well. - * - * This should only be used as a temporary measure against broken builds due - * to the change in behavior for JSON field name conflicts. * - * TODO(b/261750190) This is legacy behavior we plan to remove once downstream - * teams have had time to migrate. - * - * @deprecated + * NOTE: Do not set the option in .proto files. Always use the maps syntax + * instead. The option should only be implicitly set by the proto compiler + * parser. */ - deprecatedLegacyJsonFieldConflicts: boolean; + mapEntry: boolean; /** The parser stores options it doesn't recognize here. See above. */ uninterpretedOption: UninterpretedOption[]; } @@ -724,8 +705,11 @@ export interface FieldOptions { * check its required fields, regardless of whether or not the message has * been parsed. * - * As of May 2022, lazy verifies the contents of the byte stream during - * parsing. An invalid byte stream will cause the overall parsing to fail. + * As of 2021, lazy does no correctness checks on the byte stream during + * parsing. This may lead to crashes if and when an invalid byte stream is + * finally parsed upon access. + * + * TODO(b/211906113): Enable validation on lazy fields. */ lazy: boolean; /** @@ -743,13 +727,6 @@ export interface FieldOptions { deprecated: boolean; /** For Google-internal migration only. Do not use. */ weak: boolean; - /** - * Indicate that the field value should not be printed out when using debug - * formats, e.g. when the field contains sensitive credentials. - */ - debugRedact: boolean; - retention: FieldOptions_OptionRetention; - target: FieldOptions_OptionTargetType; /** The parser stores options it doesn't recognize here. See above. */ uninterpretedOption: UninterpretedOption[]; } @@ -836,137 +813,6 @@ export function fieldOptions_JSTypeToJSON(object: FieldOptions_JSType): string { } } -/** - * If set to RETENTION_SOURCE, the option will be omitted from the binary. - * Note: as of January 2023, support for this is in progress and does not yet - * have an effect (b/264593489). - */ -export enum FieldOptions_OptionRetention { - RETENTION_UNKNOWN = 0, - RETENTION_RUNTIME = 1, - RETENTION_SOURCE = 2, - UNRECOGNIZED = -1, -} - -export function fieldOptions_OptionRetentionFromJSON(object: any): FieldOptions_OptionRetention { - switch (object) { - case 0: - case "RETENTION_UNKNOWN": - return FieldOptions_OptionRetention.RETENTION_UNKNOWN; - case 1: - case "RETENTION_RUNTIME": - return FieldOptions_OptionRetention.RETENTION_RUNTIME; - case 2: - case "RETENTION_SOURCE": - return FieldOptions_OptionRetention.RETENTION_SOURCE; - case -1: - case "UNRECOGNIZED": - default: - return FieldOptions_OptionRetention.UNRECOGNIZED; - } -} - -export function fieldOptions_OptionRetentionToJSON(object: FieldOptions_OptionRetention): string { - switch (object) { - case FieldOptions_OptionRetention.RETENTION_UNKNOWN: - return "RETENTION_UNKNOWN"; - case FieldOptions_OptionRetention.RETENTION_RUNTIME: - return "RETENTION_RUNTIME"; - case FieldOptions_OptionRetention.RETENTION_SOURCE: - return "RETENTION_SOURCE"; - case FieldOptions_OptionRetention.UNRECOGNIZED: - default: - return "UNRECOGNIZED"; - } -} - -/** - * This indicates the types of entities that the field may apply to when used - * as an option. If it is unset, then the field may be freely used as an - * option on any kind of entity. Note: as of January 2023, support for this is - * in progress and does not yet have an effect (b/264593489). - */ -export enum FieldOptions_OptionTargetType { - TARGET_TYPE_UNKNOWN = 0, - TARGET_TYPE_FILE = 1, - TARGET_TYPE_EXTENSION_RANGE = 2, - TARGET_TYPE_MESSAGE = 3, - TARGET_TYPE_FIELD = 4, - TARGET_TYPE_ONEOF = 5, - TARGET_TYPE_ENUM = 6, - TARGET_TYPE_ENUM_ENTRY = 7, - TARGET_TYPE_SERVICE = 8, - TARGET_TYPE_METHOD = 9, - UNRECOGNIZED = -1, -} - -export function fieldOptions_OptionTargetTypeFromJSON(object: any): FieldOptions_OptionTargetType { - switch (object) { - case 0: - case "TARGET_TYPE_UNKNOWN": - return FieldOptions_OptionTargetType.TARGET_TYPE_UNKNOWN; - case 1: - case "TARGET_TYPE_FILE": - return FieldOptions_OptionTargetType.TARGET_TYPE_FILE; - case 2: - case "TARGET_TYPE_EXTENSION_RANGE": - return FieldOptions_OptionTargetType.TARGET_TYPE_EXTENSION_RANGE; - case 3: - case "TARGET_TYPE_MESSAGE": - return FieldOptions_OptionTargetType.TARGET_TYPE_MESSAGE; - case 4: - case "TARGET_TYPE_FIELD": - return FieldOptions_OptionTargetType.TARGET_TYPE_FIELD; - case 5: - case "TARGET_TYPE_ONEOF": - return FieldOptions_OptionTargetType.TARGET_TYPE_ONEOF; - case 6: - case "TARGET_TYPE_ENUM": - return FieldOptions_OptionTargetType.TARGET_TYPE_ENUM; - case 7: - case "TARGET_TYPE_ENUM_ENTRY": - return FieldOptions_OptionTargetType.TARGET_TYPE_ENUM_ENTRY; - case 8: - case "TARGET_TYPE_SERVICE": - return FieldOptions_OptionTargetType.TARGET_TYPE_SERVICE; - case 9: - case "TARGET_TYPE_METHOD": - return FieldOptions_OptionTargetType.TARGET_TYPE_METHOD; - case -1: - case "UNRECOGNIZED": - default: - return FieldOptions_OptionTargetType.UNRECOGNIZED; - } -} - -export function fieldOptions_OptionTargetTypeToJSON(object: FieldOptions_OptionTargetType): string { - switch (object) { - case FieldOptions_OptionTargetType.TARGET_TYPE_UNKNOWN: - return "TARGET_TYPE_UNKNOWN"; - case FieldOptions_OptionTargetType.TARGET_TYPE_FILE: - return "TARGET_TYPE_FILE"; - case FieldOptions_OptionTargetType.TARGET_TYPE_EXTENSION_RANGE: - return "TARGET_TYPE_EXTENSION_RANGE"; - case FieldOptions_OptionTargetType.TARGET_TYPE_MESSAGE: - return "TARGET_TYPE_MESSAGE"; - case FieldOptions_OptionTargetType.TARGET_TYPE_FIELD: - return "TARGET_TYPE_FIELD"; - case FieldOptions_OptionTargetType.TARGET_TYPE_ONEOF: - return "TARGET_TYPE_ONEOF"; - case FieldOptions_OptionTargetType.TARGET_TYPE_ENUM: - return "TARGET_TYPE_ENUM"; - case FieldOptions_OptionTargetType.TARGET_TYPE_ENUM_ENTRY: - return "TARGET_TYPE_ENUM_ENTRY"; - case FieldOptions_OptionTargetType.TARGET_TYPE_SERVICE: - return "TARGET_TYPE_SERVICE"; - case FieldOptions_OptionTargetType.TARGET_TYPE_METHOD: - return "TARGET_TYPE_METHOD"; - case FieldOptions_OptionTargetType.UNRECOGNIZED: - default: - return "UNRECOGNIZED"; - } -} - export interface OneofOptions { /** The parser stores options it doesn't recognize here. See above. */ uninterpretedOption: UninterpretedOption[]; @@ -985,17 +831,6 @@ export interface EnumOptions { * is a formalization for deprecating enums. */ deprecated: boolean; - /** - * Enable the legacy handling of JSON field name conflicts. This lowercases - * and strips underscored from the fields before comparison in proto3 only. - * The new behavior takes `json_name` into account and applies to proto2 as - * well. - * TODO(b/261750190) Remove this legacy behavior once downstream teams have - * had time to migrate. - * - * @deprecated - */ - deprecatedLegacyJsonFieldConflicts: boolean; /** The parser stores options it doesn't recognize here. See above. */ uninterpretedOption: UninterpretedOption[]; } @@ -1287,57 +1122,10 @@ export interface GeneratedCodeInfo_Annotation { begin: number; /** * Identifies the ending offset in bytes in the generated code that - * relates to the identified object. The end offset should be one past + * relates to the identified offset. The end offset should be one past * the last relevant byte (so the length of the text = end - begin). */ end: number; - semantic: GeneratedCodeInfo_Annotation_Semantic; -} - -/** - * Represents the identified object's effect on the element in the original - * .proto file. - */ -export enum GeneratedCodeInfo_Annotation_Semantic { - /** NONE - There is no effect or the effect is indescribable. */ - NONE = 0, - /** SET - The element is set or otherwise mutated. */ - SET = 1, - /** ALIAS - An alias to the element is returned. */ - ALIAS = 2, - UNRECOGNIZED = -1, -} - -export function generatedCodeInfo_Annotation_SemanticFromJSON(object: any): GeneratedCodeInfo_Annotation_Semantic { - switch (object) { - case 0: - case "NONE": - return GeneratedCodeInfo_Annotation_Semantic.NONE; - case 1: - case "SET": - return GeneratedCodeInfo_Annotation_Semantic.SET; - case 2: - case "ALIAS": - return GeneratedCodeInfo_Annotation_Semantic.ALIAS; - case -1: - case "UNRECOGNIZED": - default: - return GeneratedCodeInfo_Annotation_Semantic.UNRECOGNIZED; - } -} - -export function generatedCodeInfo_Annotation_SemanticToJSON(object: GeneratedCodeInfo_Annotation_Semantic): string { - switch (object) { - case GeneratedCodeInfo_Annotation_Semantic.NONE: - return "NONE"; - case GeneratedCodeInfo_Annotation_Semantic.SET: - return "SET"; - case GeneratedCodeInfo_Annotation_Semantic.ALIAS: - return "ALIAS"; - case GeneratedCodeInfo_Annotation_Semantic.UNRECOGNIZED: - default: - return "UNRECOGNIZED"; - } } function createBaseFileDescriptorSet(): FileDescriptorSet { @@ -1414,7 +1202,6 @@ function createBaseFileDescriptorProto(): FileDescriptorProto { options: undefined, sourceCodeInfo: undefined, syntax: "", - edition: "", }; } @@ -1460,9 +1247,6 @@ export const FileDescriptorProto = { if (message.syntax !== "") { writer.uint32(98).string(message.syntax); } - if (message.edition !== "") { - writer.uint32(106).string(message.edition); - } return writer; }, @@ -1577,13 +1361,6 @@ export const FileDescriptorProto = { message.syntax = reader.string(); continue; - case 13: - if (tag !== 106) { - break; - } - - message.edition = reader.string(); - continue; } if ((tag & 7) === 4 || tag === 0) { break; @@ -1613,7 +1390,6 @@ export const FileDescriptorProto = { options: isSet(object.options) ? FileOptions.fromJSON(object.options) : undefined, sourceCodeInfo: isSet(object.sourceCodeInfo) ? SourceCodeInfo.fromJSON(object.sourceCodeInfo) : undefined, syntax: isSet(object.syntax) ? String(object.syntax) : "", - edition: isSet(object.edition) ? String(object.edition) : "", }; }, @@ -1660,7 +1436,6 @@ export const FileDescriptorProto = { message.sourceCodeInfo !== undefined && (obj.sourceCodeInfo = message.sourceCodeInfo ? SourceCodeInfo.toJSON(message.sourceCodeInfo) : undefined); message.syntax !== undefined && (obj.syntax = message.syntax); - message.edition !== undefined && (obj.edition = message.edition); return obj; }, @@ -1686,7 +1461,6 @@ export const FileDescriptorProto = { ? SourceCodeInfo.fromPartial(object.sourceCodeInfo) : undefined; message.syntax = object.syntax ?? ""; - message.edition = object.edition ?? ""; return message; }, }; @@ -3287,7 +3061,6 @@ function createBaseMessageOptions(): MessageOptions { noStandardDescriptorAccessor: false, deprecated: false, mapEntry: false, - deprecatedLegacyJsonFieldConflicts: false, uninterpretedOption: [], }; } @@ -3306,9 +3079,6 @@ export const MessageOptions = { if (message.mapEntry === true) { writer.uint32(56).bool(message.mapEntry); } - if (message.deprecatedLegacyJsonFieldConflicts === true) { - writer.uint32(88).bool(message.deprecatedLegacyJsonFieldConflicts); - } for (const v of message.uninterpretedOption) { UninterpretedOption.encode(v!, writer.uint32(7994).fork()).ldelim(); } @@ -3350,13 +3120,6 @@ export const MessageOptions = { message.mapEntry = reader.bool(); continue; - case 11: - if (tag !== 88) { - break; - } - - message.deprecatedLegacyJsonFieldConflicts = reader.bool(); - continue; case 999: if (tag !== 7994) { break; @@ -3381,9 +3144,6 @@ export const MessageOptions = { : false, deprecated: isSet(object.deprecated) ? Boolean(object.deprecated) : false, mapEntry: isSet(object.mapEntry) ? Boolean(object.mapEntry) : false, - deprecatedLegacyJsonFieldConflicts: isSet(object.deprecatedLegacyJsonFieldConflicts) - ? Boolean(object.deprecatedLegacyJsonFieldConflicts) - : false, uninterpretedOption: Array.isArray(object?.uninterpretedOption) ? object.uninterpretedOption.map((e: any) => UninterpretedOption.fromJSON(e)) : [], @@ -3397,8 +3157,6 @@ export const MessageOptions = { (obj.noStandardDescriptorAccessor = message.noStandardDescriptorAccessor); message.deprecated !== undefined && (obj.deprecated = message.deprecated); message.mapEntry !== undefined && (obj.mapEntry = message.mapEntry); - message.deprecatedLegacyJsonFieldConflicts !== undefined && - (obj.deprecatedLegacyJsonFieldConflicts = message.deprecatedLegacyJsonFieldConflicts); if (message.uninterpretedOption) { obj.uninterpretedOption = message.uninterpretedOption.map((e) => e ? UninterpretedOption.toJSON(e) : undefined); } else { @@ -3417,7 +3175,6 @@ export const MessageOptions = { message.noStandardDescriptorAccessor = object.noStandardDescriptorAccessor ?? false; message.deprecated = object.deprecated ?? false; message.mapEntry = object.mapEntry ?? false; - message.deprecatedLegacyJsonFieldConflicts = object.deprecatedLegacyJsonFieldConflicts ?? false; message.uninterpretedOption = object.uninterpretedOption?.map((e) => UninterpretedOption.fromPartial(e)) || []; return message; }, @@ -3432,9 +3189,6 @@ function createBaseFieldOptions(): FieldOptions { unverifiedLazy: false, deprecated: false, weak: false, - debugRedact: false, - retention: 0, - target: 0, uninterpretedOption: [], }; } @@ -3462,15 +3216,6 @@ export const FieldOptions = { if (message.weak === true) { writer.uint32(80).bool(message.weak); } - if (message.debugRedact === true) { - writer.uint32(128).bool(message.debugRedact); - } - if (message.retention !== 0) { - writer.uint32(136).int32(message.retention); - } - if (message.target !== 0) { - writer.uint32(144).int32(message.target); - } for (const v of message.uninterpretedOption) { UninterpretedOption.encode(v!, writer.uint32(7994).fork()).ldelim(); } @@ -3533,27 +3278,6 @@ export const FieldOptions = { message.weak = reader.bool(); continue; - case 16: - if (tag !== 128) { - break; - } - - message.debugRedact = reader.bool(); - continue; - case 17: - if (tag !== 136) { - break; - } - - message.retention = reader.int32() as any; - continue; - case 18: - if (tag !== 144) { - break; - } - - message.target = reader.int32() as any; - continue; case 999: if (tag !== 7994) { break; @@ -3579,9 +3303,6 @@ export const FieldOptions = { unverifiedLazy: isSet(object.unverifiedLazy) ? Boolean(object.unverifiedLazy) : false, deprecated: isSet(object.deprecated) ? Boolean(object.deprecated) : false, weak: isSet(object.weak) ? Boolean(object.weak) : false, - debugRedact: isSet(object.debugRedact) ? Boolean(object.debugRedact) : false, - retention: isSet(object.retention) ? fieldOptions_OptionRetentionFromJSON(object.retention) : 0, - target: isSet(object.target) ? fieldOptions_OptionTargetTypeFromJSON(object.target) : 0, uninterpretedOption: Array.isArray(object?.uninterpretedOption) ? object.uninterpretedOption.map((e: any) => UninterpretedOption.fromJSON(e)) : [], @@ -3597,9 +3318,6 @@ export const FieldOptions = { message.unverifiedLazy !== undefined && (obj.unverifiedLazy = message.unverifiedLazy); message.deprecated !== undefined && (obj.deprecated = message.deprecated); message.weak !== undefined && (obj.weak = message.weak); - message.debugRedact !== undefined && (obj.debugRedact = message.debugRedact); - message.retention !== undefined && (obj.retention = fieldOptions_OptionRetentionToJSON(message.retention)); - message.target !== undefined && (obj.target = fieldOptions_OptionTargetTypeToJSON(message.target)); if (message.uninterpretedOption) { obj.uninterpretedOption = message.uninterpretedOption.map((e) => e ? UninterpretedOption.toJSON(e) : undefined); } else { @@ -3621,9 +3339,6 @@ export const FieldOptions = { message.unverifiedLazy = object.unverifiedLazy ?? false; message.deprecated = object.deprecated ?? false; message.weak = object.weak ?? false; - message.debugRedact = object.debugRedact ?? false; - message.retention = object.retention ?? 0; - message.target = object.target ?? 0; message.uninterpretedOption = object.uninterpretedOption?.map((e) => UninterpretedOption.fromPartial(e)) || []; return message; }, @@ -3694,7 +3409,7 @@ export const OneofOptions = { }; function createBaseEnumOptions(): EnumOptions { - return { allowAlias: false, deprecated: false, deprecatedLegacyJsonFieldConflicts: false, uninterpretedOption: [] }; + return { allowAlias: false, deprecated: false, uninterpretedOption: [] }; } export const EnumOptions = { @@ -3705,9 +3420,6 @@ export const EnumOptions = { if (message.deprecated === true) { writer.uint32(24).bool(message.deprecated); } - if (message.deprecatedLegacyJsonFieldConflicts === true) { - writer.uint32(48).bool(message.deprecatedLegacyJsonFieldConflicts); - } for (const v of message.uninterpretedOption) { UninterpretedOption.encode(v!, writer.uint32(7994).fork()).ldelim(); } @@ -3735,13 +3447,6 @@ export const EnumOptions = { message.deprecated = reader.bool(); continue; - case 6: - if (tag !== 48) { - break; - } - - message.deprecatedLegacyJsonFieldConflicts = reader.bool(); - continue; case 999: if (tag !== 7994) { break; @@ -3762,9 +3467,6 @@ export const EnumOptions = { return { allowAlias: isSet(object.allowAlias) ? Boolean(object.allowAlias) : false, deprecated: isSet(object.deprecated) ? Boolean(object.deprecated) : false, - deprecatedLegacyJsonFieldConflicts: isSet(object.deprecatedLegacyJsonFieldConflicts) - ? Boolean(object.deprecatedLegacyJsonFieldConflicts) - : false, uninterpretedOption: Array.isArray(object?.uninterpretedOption) ? object.uninterpretedOption.map((e: any) => UninterpretedOption.fromJSON(e)) : [], @@ -3775,8 +3477,6 @@ export const EnumOptions = { const obj: any = {}; message.allowAlias !== undefined && (obj.allowAlias = message.allowAlias); message.deprecated !== undefined && (obj.deprecated = message.deprecated); - message.deprecatedLegacyJsonFieldConflicts !== undefined && - (obj.deprecatedLegacyJsonFieldConflicts = message.deprecatedLegacyJsonFieldConflicts); if (message.uninterpretedOption) { obj.uninterpretedOption = message.uninterpretedOption.map((e) => e ? UninterpretedOption.toJSON(e) : undefined); } else { @@ -3793,7 +3493,6 @@ export const EnumOptions = { const message = createBaseEnumOptions(); message.allowAlias = object.allowAlias ?? false; message.deprecated = object.deprecated ?? false; - message.deprecatedLegacyJsonFieldConflicts = object.deprecatedLegacyJsonFieldConflicts ?? false; message.uninterpretedOption = object.uninterpretedOption?.map((e) => UninterpretedOption.fromPartial(e)) || []; return message; }, @@ -4543,7 +4242,7 @@ export const GeneratedCodeInfo = { }; function createBaseGeneratedCodeInfo_Annotation(): GeneratedCodeInfo_Annotation { - return { path: [], sourceFile: "", begin: 0, end: 0, semantic: 0 }; + return { path: [], sourceFile: "", begin: 0, end: 0 }; } export const GeneratedCodeInfo_Annotation = { @@ -4562,9 +4261,6 @@ export const GeneratedCodeInfo_Annotation = { if (message.end !== 0) { writer.uint32(32).int32(message.end); } - if (message.semantic !== 0) { - writer.uint32(40).int32(message.semantic); - } return writer; }, @@ -4613,13 +4309,6 @@ export const GeneratedCodeInfo_Annotation = { message.end = reader.int32(); continue; - case 5: - if (tag !== 40) { - break; - } - - message.semantic = reader.int32() as any; - continue; } if ((tag & 7) === 4 || tag === 0) { break; @@ -4635,7 +4324,6 @@ export const GeneratedCodeInfo_Annotation = { sourceFile: isSet(object.sourceFile) ? String(object.sourceFile) : "", begin: isSet(object.begin) ? Number(object.begin) : 0, end: isSet(object.end) ? Number(object.end) : 0, - semantic: isSet(object.semantic) ? generatedCodeInfo_Annotation_SemanticFromJSON(object.semantic) : 0, }; }, @@ -4649,7 +4337,6 @@ export const GeneratedCodeInfo_Annotation = { message.sourceFile !== undefined && (obj.sourceFile = message.sourceFile); message.begin !== undefined && (obj.begin = Math.round(message.begin)); message.end !== undefined && (obj.end = Math.round(message.end)); - message.semantic !== undefined && (obj.semantic = generatedCodeInfo_Annotation_SemanticToJSON(message.semantic)); return obj; }, @@ -4663,7 +4350,6 @@ export const GeneratedCodeInfo_Annotation = { message.sourceFile = object.sourceFile ?? ""; message.begin = object.begin ?? 0; message.end = object.end ?? 0; - message.semantic = object.semantic ?? 0; return message; }, }; diff --git a/app/controlplane/api/gen/frontend/workflowcontract/v1/crafting_schema.ts b/app/controlplane/api/gen/frontend/workflowcontract/v1/crafting_schema.ts index fdfbaf18a..063330617 100644 --- a/app/controlplane/api/gen/frontend/workflowcontract/v1/crafting_schema.ts +++ b/app/controlplane/api/gen/frontend/workflowcontract/v1/crafting_schema.ts @@ -13,6 +13,12 @@ export interface CraftingSchema { materials: CraftingSchema_Material[]; envAllowList: string[]; runner?: CraftingSchema_Runner; + /** + * List of annotations that can be used to add metadata to the attestation + * this metadata can be used later on by the integrations engine to filter and interpolate data + * It works in addition to the annotations defined in the materials and the runner + */ + annotations: Annotation[]; } export interface CraftingSchema_Runner { @@ -150,7 +156,7 @@ export interface Annotation { } function createBaseCraftingSchema(): CraftingSchema { - return { schemaVersion: "", materials: [], envAllowList: [], runner: undefined }; + return { schemaVersion: "", materials: [], envAllowList: [], runner: undefined, annotations: [] }; } export const CraftingSchema = { @@ -167,6 +173,9 @@ export const CraftingSchema = { if (message.runner !== undefined) { CraftingSchema_Runner.encode(message.runner, writer.uint32(34).fork()).ldelim(); } + for (const v of message.annotations) { + Annotation.encode(v!, writer.uint32(42).fork()).ldelim(); + } return writer; }, @@ -205,6 +214,13 @@ export const CraftingSchema = { message.runner = CraftingSchema_Runner.decode(reader, reader.uint32()); continue; + case 5: + if (tag !== 42) { + break; + } + + message.annotations.push(Annotation.decode(reader, reader.uint32())); + continue; } if ((tag & 7) === 4 || tag === 0) { break; @@ -222,6 +238,7 @@ export const CraftingSchema = { : [], envAllowList: Array.isArray(object?.envAllowList) ? object.envAllowList.map((e: any) => String(e)) : [], runner: isSet(object.runner) ? CraftingSchema_Runner.fromJSON(object.runner) : undefined, + annotations: Array.isArray(object?.annotations) ? object.annotations.map((e: any) => Annotation.fromJSON(e)) : [], }; }, @@ -240,6 +257,11 @@ export const CraftingSchema = { } message.runner !== undefined && (obj.runner = message.runner ? CraftingSchema_Runner.toJSON(message.runner) : undefined); + if (message.annotations) { + obj.annotations = message.annotations.map((e) => e ? Annotation.toJSON(e) : undefined); + } else { + obj.annotations = []; + } return obj; }, @@ -255,6 +277,7 @@ export const CraftingSchema = { message.runner = (object.runner !== undefined && object.runner !== null) ? CraftingSchema_Runner.fromPartial(object.runner) : undefined; + message.annotations = object.annotations?.map((e) => Annotation.fromPartial(e)) || []; return message; }, }; diff --git a/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.go b/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.go index a71e20e87..a7d06b313 100644 --- a/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.go +++ b/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.go @@ -161,6 +161,10 @@ type CraftingSchema struct { Materials []*CraftingSchema_Material `protobuf:"bytes,2,rep,name=materials,proto3" json:"materials,omitempty"` EnvAllowList []string `protobuf:"bytes,3,rep,name=env_allow_list,json=envAllowList,proto3" json:"env_allow_list,omitempty"` Runner *CraftingSchema_Runner `protobuf:"bytes,4,opt,name=runner,proto3" json:"runner,omitempty"` + // List of annotations that can be used to add metadata to the attestation + // this metadata can be used later on by the integrations engine to filter and interpolate data + // It works in addition to the annotations defined in the materials and the runner + Annotations []*Annotation `protobuf:"bytes,5,rep,name=annotations,proto3" json:"annotations,omitempty"` } func (x *CraftingSchema) Reset() { @@ -223,6 +227,13 @@ func (x *CraftingSchema) GetRunner() *CraftingSchema_Runner { return nil } +func (x *CraftingSchema) GetAnnotations() []*Annotation { + if x != nil { + return x.Annotations + } + return nil +} + type Annotation struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -416,7 +427,7 @@ var file_workflowcontract_v1_crafting_schema_proto_rawDesc = []byte{ 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdd, 0x06, 0x0a, 0x0e, 0x43, 0x72, + 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa0, 0x07, 0x0a, 0x0e, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x30, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x72, 0x04, 0x0a, 0x02, 0x76, 0x31, 0x52, @@ -432,55 +443,59 @@ var file_workflowcontract_v1_crafting_schema_proto_rawDesc = []byte{ 0x32, 0x2a, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x06, 0x72, 0x75, - 0x6e, 0x6e, 0x65, 0x72, 0x1a, 0xc4, 0x01, 0x0a, 0x06, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x12, - 0x53, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, + 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0xc4, 0x01, 0x0a, 0x06, 0x52, 0x75, 0x6e, 0x6e, + 0x65, 0x72, 0x12, 0x53, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x35, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x75, 0x6e, + 0x6e, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x20, + 0x00, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x65, 0x0a, 0x0a, 0x52, 0x75, 0x6e, 0x6e, 0x65, + 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x55, 0x4e, 0x4e, 0x45, 0x52, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42, 0x5f, 0x41, 0x43, 0x54, + 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x47, 0x49, 0x54, 0x4c, 0x41, 0x42, 0x5f, + 0x50, 0x49, 0x50, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x41, 0x5a, + 0x55, 0x52, 0x45, 0x5f, 0x50, 0x49, 0x50, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x03, 0x1a, 0x9b, + 0x03, 0x0a, 0x08, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x12, 0x57, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4d, + 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x20, 0x00, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x22, 0x65, 0x0a, 0x0a, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x55, 0x4e, 0x4e, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x11, 0x0a, 0x0d, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, - 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x47, 0x49, 0x54, 0x4c, 0x41, 0x42, 0x5f, 0x50, 0x49, 0x50, - 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x41, 0x5a, 0x55, 0x52, 0x45, - 0x5f, 0x50, 0x49, 0x50, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x03, 0x1a, 0x9b, 0x03, 0x0a, 0x08, - 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x12, 0x57, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x61, - 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4d, 0x61, 0x74, 0x65, - 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, - 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x20, 0x00, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x12, 0x24, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x10, 0xfa, 0x42, 0x0d, 0x72, 0x0b, 0x32, 0x09, 0x5e, 0x5b, 0x5c, 0x77, 0x7c, 0x2d, 0x5d, 0x2b, - 0x24, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x41, 0x0a, 0x0b, 0x61, - 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x98, - 0x01, 0x0a, 0x0c, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x1d, 0x0a, 0x19, 0x4d, 0x41, 0x54, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, - 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x4f, - 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x10, 0x02, 0x12, - 0x0c, 0x0a, 0x08, 0x41, 0x52, 0x54, 0x49, 0x46, 0x41, 0x43, 0x54, 0x10, 0x03, 0x12, 0x17, 0x0a, - 0x13, 0x53, 0x42, 0x4f, 0x4d, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x4f, 0x4e, 0x45, 0x44, 0x58, 0x5f, - 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x42, 0x4f, 0x4d, 0x5f, 0x53, - 0x50, 0x44, 0x58, 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x0d, 0x0a, 0x09, 0x4a, 0x55, - 0x4e, 0x49, 0x54, 0x5f, 0x58, 0x4d, 0x4c, 0x10, 0x06, 0x22, 0x46, 0x0a, 0x0a, 0x41, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xfa, 0x42, 0x0b, 0x72, 0x09, 0x32, 0x07, 0x5e, 0x5b, - 0x5c, 0x77, 0x5d, 0x2b, 0x24, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x42, 0x4d, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x77, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2f, 0x76, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x10, 0xfa, 0x42, 0x0d, 0x72, 0x0b, 0x32, 0x09, 0x5e, 0x5b, 0x5c, 0x77, 0x7c, + 0x2d, 0x5d, 0x2b, 0x24, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x41, + 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x98, 0x01, 0x0a, 0x0c, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x41, 0x54, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x13, 0x0a, + 0x0f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x49, 0x4d, 0x41, 0x47, 0x45, + 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x52, 0x54, 0x49, 0x46, 0x41, 0x43, 0x54, 0x10, 0x03, + 0x12, 0x17, 0x0a, 0x13, 0x53, 0x42, 0x4f, 0x4d, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x4f, 0x4e, 0x45, + 0x44, 0x58, 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x42, 0x4f, + 0x4d, 0x5f, 0x53, 0x50, 0x44, 0x58, 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x0d, 0x0a, + 0x09, 0x4a, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x58, 0x4d, 0x4c, 0x10, 0x06, 0x22, 0x46, 0x0a, 0x0a, + 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xfa, 0x42, 0x0b, 0x72, 0x09, 0x32, + 0x07, 0x5e, 0x5b, 0x5c, 0x77, 0x5d, 0x2b, 0x24, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4d, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, + 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -508,14 +523,15 @@ var file_workflowcontract_v1_crafting_schema_proto_goTypes = []interface{}{ var file_workflowcontract_v1_crafting_schema_proto_depIdxs = []int32{ 5, // 0: workflowcontract.v1.CraftingSchema.materials:type_name -> workflowcontract.v1.CraftingSchema.Material 4, // 1: workflowcontract.v1.CraftingSchema.runner:type_name -> workflowcontract.v1.CraftingSchema.Runner - 0, // 2: workflowcontract.v1.CraftingSchema.Runner.type:type_name -> workflowcontract.v1.CraftingSchema.Runner.RunnerType - 1, // 3: workflowcontract.v1.CraftingSchema.Material.type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType - 3, // 4: workflowcontract.v1.CraftingSchema.Material.annotations:type_name -> workflowcontract.v1.Annotation - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 3, // 2: workflowcontract.v1.CraftingSchema.annotations:type_name -> workflowcontract.v1.Annotation + 0, // 3: workflowcontract.v1.CraftingSchema.Runner.type:type_name -> workflowcontract.v1.CraftingSchema.Runner.RunnerType + 1, // 4: workflowcontract.v1.CraftingSchema.Material.type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType + 3, // 5: workflowcontract.v1.CraftingSchema.Material.annotations:type_name -> workflowcontract.v1.Annotation + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_workflowcontract_v1_crafting_schema_proto_init() } diff --git a/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.validate.go b/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.validate.go index 26ea19829..03c797753 100644 --- a/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.validate.go +++ b/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.validate.go @@ -131,6 +131,40 @@ func (m *CraftingSchema) validate(all bool) error { } } + for idx, item := range m.GetAnnotations() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, CraftingSchemaValidationError{ + field: fmt.Sprintf("Annotations[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, CraftingSchemaValidationError{ + field: fmt.Sprintf("Annotations[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return CraftingSchemaValidationError{ + field: fmt.Sprintf("Annotations[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + if len(errors) > 0 { return CraftingSchemaMultiError(errors) } diff --git a/app/controlplane/api/workflowcontract/v1/crafting_schema.proto b/app/controlplane/api/workflowcontract/v1/crafting_schema.proto index eb8a1f946..38dd755a1 100644 --- a/app/controlplane/api/workflowcontract/v1/crafting_schema.proto +++ b/app/controlplane/api/workflowcontract/v1/crafting_schema.proto @@ -29,6 +29,10 @@ message CraftingSchema { repeated Material materials = 2; repeated string env_allow_list = 3; Runner runner = 4; + // List of annotations that can be used to add metadata to the attestation + // this metadata can be used later on by the integrations engine to filter and interpolate data + // It works in addition to the annotations defined in the materials and the runner + repeated Annotation annotations = 5; message Runner { RunnerType type = 1 [(validate.rules).enum = {not_in: [0]}]; diff --git a/common.mk b/common.mk index 3eba2349c..86cf4955e 100644 --- a/common.mk +++ b/common.mk @@ -3,7 +3,7 @@ VERSION=$(shell git describe --tags --always) .PHONY: init # init env init: - go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.30.0 + go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.31.0 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 go install github.com/envoyproxy/protoc-gen-validate@v1.0.1 go install github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2@latest diff --git a/internal/attestation/renderer/chainloop/chainloop.go b/internal/attestation/renderer/chainloop/chainloop.go index 68f67c941..9f0002356 100644 --- a/internal/attestation/renderer/chainloop/chainloop.go +++ b/internal/attestation/renderer/chainloop/chainloop.go @@ -66,6 +66,8 @@ type ProvenancePredicateCommon struct { Env map[string]string `json:"env,omitempty"` RunnerType string `json:"runnerType"` RunnerURL string `json:"runnerURL,omitempty"` + // Custom annotations + Annotations map[string]string `json:"annotations,omitempty"` } type Metadata struct { @@ -95,12 +97,13 @@ type RendererCommon struct { func predicateCommon(builderInfo *builderInfo, att *v1.Attestation) *ProvenancePredicateCommon { return &ProvenancePredicateCommon{ - BuildType: chainloopBuildType, - Builder: &slsacommon.ProvenanceBuilder{ID: fmt.Sprintf(builderIDFmt, builderInfo.version, builderInfo.digest)}, - Metadata: getChainloopMeta(att), - Env: att.EnvVars, - RunnerType: att.GetRunnerType().String(), - RunnerURL: att.GetRunnerUrl(), + BuildType: chainloopBuildType, + Builder: &slsacommon.ProvenanceBuilder{ID: fmt.Sprintf(builderIDFmt, builderInfo.version, builderInfo.digest)}, + Metadata: getChainloopMeta(att), + Env: att.EnvVars, + RunnerType: att.GetRunnerType().String(), + RunnerURL: att.GetRunnerUrl(), + Annotations: att.Annotations, } }