diff --git a/backend/protos/xyz/block/ftl/v1beta1/provisioner/resource.pb.go b/backend/protos/xyz/block/ftl/v1beta1/provisioner/resource.pb.go index f83e3ec7f..0e62ae9db 100644 --- a/backend/protos/xyz/block/ftl/v1beta1/provisioner/resource.pb.go +++ b/backend/protos/xyz/block/ftl/v1beta1/provisioner/resource.pb.go @@ -36,6 +36,7 @@ type Resource struct { // *Resource_Postgres // *Resource_Mysql // *Resource_Module + // *Resource_Migration Resource isResource_Resource `protobuf_oneof:"resource"` } @@ -104,6 +105,13 @@ func (x *Resource) GetModule() *ModuleResource { return nil } +func (x *Resource) GetMigration() *MigrationResource { + if x, ok := x.GetResource().(*Resource_Migration); ok { + return x.Migration + } + return nil +} + type isResource_Resource interface { isResource_Resource() } @@ -120,12 +128,18 @@ type Resource_Module struct { Module *ModuleResource `protobuf:"bytes,104,opt,name=module,proto3,oneof"` } +type Resource_Migration struct { + Migration *MigrationResource `protobuf:"bytes,105,opt,name=migration,proto3,oneof"` +} + func (*Resource_Postgres) isResource_Resource() {} func (*Resource_Mysql) isResource_Resource() {} func (*Resource_Module) isResource_Resource() {} +func (*Resource_Migration) isResource_Resource() {} + type PostgresResource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -216,6 +230,59 @@ func (x *MysqlResource) GetOutput() *MysqlResource_MysqlResourceOutput { return nil } +type MigrationResource struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Output *MigrationResource_MigrationResourceOutput `protobuf:"bytes,1,opt,name=output,proto3" json:"output,omitempty"` + Digest string `protobuf:"bytes,2,opt,name=digest,proto3" json:"digest,omitempty"` +} + +func (x *MigrationResource) Reset() { + *x = MigrationResource{} + mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MigrationResource) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MigrationResource) ProtoMessage() {} + +func (x *MigrationResource) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MigrationResource.ProtoReflect.Descriptor instead. +func (*MigrationResource) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_v1beta1_provisioner_resource_proto_rawDescGZIP(), []int{3} +} + +func (x *MigrationResource) GetOutput() *MigrationResource_MigrationResourceOutput { + if x != nil { + return x.Output + } + return nil +} + +func (x *MigrationResource) GetDigest() string { + if x != nil { + return x.Digest + } + return "" +} + type ModuleResource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -230,7 +297,7 @@ type ModuleResource struct { func (x *ModuleResource) Reset() { *x = ModuleResource{} - mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[3] + mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -242,7 +309,7 @@ func (x *ModuleResource) String() string { func (*ModuleResource) ProtoMessage() {} func (x *ModuleResource) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[3] + mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -255,7 +322,7 @@ func (x *ModuleResource) ProtoReflect() protoreflect.Message { // Deprecated: Use ModuleResource.ProtoReflect.Descriptor instead. func (*ModuleResource) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1beta1_provisioner_resource_proto_rawDescGZIP(), []int{3} + return file_xyz_block_ftl_v1beta1_provisioner_resource_proto_rawDescGZIP(), []int{4} } func (x *ModuleResource) GetOutput() *ModuleResource_ModuleResourceOutput { @@ -297,7 +364,7 @@ type PostgresResource_PostgresResourceOutput struct { func (x *PostgresResource_PostgresResourceOutput) Reset() { *x = PostgresResource_PostgresResourceOutput{} - mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[4] + mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -309,7 +376,7 @@ func (x *PostgresResource_PostgresResourceOutput) String() string { func (*PostgresResource_PostgresResourceOutput) ProtoMessage() {} func (x *PostgresResource_PostgresResourceOutput) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[4] + mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -350,7 +417,7 @@ type MysqlResource_MysqlResourceOutput struct { func (x *MysqlResource_MysqlResourceOutput) Reset() { *x = MysqlResource_MysqlResourceOutput{} - mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[5] + mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -362,7 +429,7 @@ func (x *MysqlResource_MysqlResourceOutput) String() string { func (*MysqlResource_MysqlResourceOutput) ProtoMessage() {} func (x *MysqlResource_MysqlResourceOutput) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[5] + mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -392,6 +459,42 @@ func (x *MysqlResource_MysqlResourceOutput) GetWriteDsn() string { return "" } +type MigrationResource_MigrationResourceOutput struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *MigrationResource_MigrationResourceOutput) Reset() { + *x = MigrationResource_MigrationResourceOutput{} + mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MigrationResource_MigrationResourceOutput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MigrationResource_MigrationResourceOutput) ProtoMessage() {} + +func (x *MigrationResource_MigrationResourceOutput) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MigrationResource_MigrationResourceOutput.ProtoReflect.Descriptor instead. +func (*MigrationResource_MigrationResourceOutput) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_v1beta1_provisioner_resource_proto_rawDescGZIP(), []int{3, 0} +} + type ModuleResource_ModuleResourceOutput struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -402,7 +505,7 @@ type ModuleResource_ModuleResourceOutput struct { func (x *ModuleResource_ModuleResourceOutput) Reset() { *x = ModuleResource_ModuleResourceOutput{} - mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[6] + mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -414,7 +517,7 @@ func (x *ModuleResource_ModuleResourceOutput) String() string { func (*ModuleResource_ModuleResourceOutput) ProtoMessage() {} func (x *ModuleResource_ModuleResourceOutput) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[6] + mi := &file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -427,7 +530,7 @@ func (x *ModuleResource_ModuleResourceOutput) ProtoReflect() protoreflect.Messag // Deprecated: Use ModuleResource_ModuleResourceOutput.ProtoReflect.Descriptor instead. func (*ModuleResource_ModuleResourceOutput) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1beta1_provisioner_resource_proto_rawDescGZIP(), []int{3, 0} + return file_xyz_block_ftl_v1beta1_provisioner_resource_proto_rawDescGZIP(), []int{4, 0} } func (x *ModuleResource_ModuleResourceOutput) GetDeploymentKey() string { @@ -451,7 +554,7 @@ var file_xyz_block_ftl_v1beta1_provisioner_resource_proto_rawDesc = []byte{ 0x74, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x78, 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2f, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa1, 0x02, 0x0a, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf7, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x51, 0x0a, 0x08, 0x70, 0x6f, @@ -469,61 +572,78 @@ var file_xyz_block_ftl_v1beta1_provisioner_resource_proto_rawDesc = []byte{ 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x6f, - 0x64, 0x75, 0x6c, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x22, 0xc8, 0x01, 0x0a, 0x10, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4a, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x67, - 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x1a, 0x50, 0x0a, 0x16, 0x50, 0x6f, 0x73, - 0x74, 0x67, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x64, 0x73, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x61, 0x64, 0x44, 0x73, 0x6e, 0x12, 0x1b, - 0x0a, 0x09, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x64, 0x73, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, 0x65, 0x44, 0x73, 0x6e, 0x22, 0xbc, 0x01, 0x0a, 0x0d, - 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x5c, 0x0a, - 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x44, 0x2e, - 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, - 0x72, 0x2e, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, - 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x1a, 0x4d, 0x0a, 0x13, 0x4d, - 0x79, 0x73, 0x71, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x64, 0x73, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x61, 0x64, 0x44, 0x73, 0x6e, 0x12, 0x1b, 0x0a, - 0x09, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x64, 0x73, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, 0x65, 0x44, 0x73, 0x6e, 0x22, 0xed, 0x02, 0x0a, 0x0e, 0x4d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x5e, 0x0a, - 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x46, 0x2e, - 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, - 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x37, 0x0a, - 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, - 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, - 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x06, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x42, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x65, 0x66, 0x61, - 0x63, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, - 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x52, - 0x09, 0x61, 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x34, 0x0a, 0x06, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, - 0x75, 0x63, 0x74, 0x48, 0x00, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x88, 0x01, 0x01, - 0x1a, 0x3d, 0x0a, 0x14, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x65, 0x70, 0x6c, - 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0d, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x42, - 0x09, 0x0a, 0x07, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x42, 0x5b, 0x50, 0x01, 0x5a, 0x57, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x42, 0x44, 0x35, 0x34, - 0x35, 0x36, 0x36, 0x39, 0x37, 0x35, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, - 0x6e, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x78, 0x79, 0x7a, 0x2f, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x64, 0x75, 0x6c, 0x65, 0x12, 0x54, 0x0a, 0x09, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x69, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x00, 0x52, + 0x09, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0xc8, 0x01, 0x0a, 0x10, 0x50, 0x6f, 0x73, 0x74, 0x67, + 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x06, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4a, 0x2e, 0x78, 0x79, + 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, + 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x1a, + 0x50, 0x0a, 0x16, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x61, + 0x64, 0x5f, 0x64, 0x73, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x61, + 0x64, 0x44, 0x73, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x64, 0x73, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, 0x65, 0x44, 0x73, + 0x6e, 0x22, 0xbc, 0x01, 0x0a, 0x0d, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x5c, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, + 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x1a, 0x4d, 0x0a, 0x13, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x61, 0x64, + 0x5f, 0x64, 0x73, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x61, 0x64, + 0x44, 0x73, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x64, 0x73, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, 0x65, 0x44, 0x73, 0x6e, + 0x22, 0xac, 0x01, 0x0a, 0x11, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x64, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4c, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4d, 0x69, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, + 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, + 0x67, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x0a, 0x17, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, + 0xed, 0x02, 0x0a, 0x0e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x46, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, + 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, + 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x42, 0x0a, 0x09, 0x61, + 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, + 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, + 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x72, 0x74, 0x65, + 0x66, 0x61, 0x63, 0x74, 0x52, 0x09, 0x61, 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, + 0x34, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x00, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x88, 0x01, 0x01, 0x1a, 0x3d, 0x0a, 0x14, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x25, 0x0a, + 0x0e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x4b, 0x65, 0x79, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x42, + 0x5b, 0x50, 0x01, 0x5a, 0x57, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x54, 0x42, 0x44, 0x35, 0x34, 0x35, 0x36, 0x36, 0x39, 0x37, 0x35, 0x2f, 0x66, 0x74, 0x6c, 0x2f, + 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x78, + 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, + 0x3b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -538,34 +658,38 @@ func file_xyz_block_ftl_v1beta1_provisioner_resource_proto_rawDescGZIP() []byte return file_xyz_block_ftl_v1beta1_provisioner_resource_proto_rawDescData } -var file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 9) var file_xyz_block_ftl_v1beta1_provisioner_resource_proto_goTypes = []any{ - (*Resource)(nil), // 0: xyz.block.ftl.v1beta1.provisioner.Resource - (*PostgresResource)(nil), // 1: xyz.block.ftl.v1beta1.provisioner.PostgresResource - (*MysqlResource)(nil), // 2: xyz.block.ftl.v1beta1.provisioner.MysqlResource - (*ModuleResource)(nil), // 3: xyz.block.ftl.v1beta1.provisioner.ModuleResource - (*PostgresResource_PostgresResourceOutput)(nil), // 4: xyz.block.ftl.v1beta1.provisioner.PostgresResource.PostgresResourceOutput - (*MysqlResource_MysqlResourceOutput)(nil), // 5: xyz.block.ftl.v1beta1.provisioner.MysqlResource.MysqlResourceOutput - (*ModuleResource_ModuleResourceOutput)(nil), // 6: xyz.block.ftl.v1beta1.provisioner.ModuleResource.ModuleResourceOutput - (*schema.Module)(nil), // 7: xyz.block.ftl.v1.schema.Module - (*v1.DeploymentArtefact)(nil), // 8: xyz.block.ftl.v1.DeploymentArtefact - (*structpb.Struct)(nil), // 9: google.protobuf.Struct + (*Resource)(nil), // 0: xyz.block.ftl.v1beta1.provisioner.Resource + (*PostgresResource)(nil), // 1: xyz.block.ftl.v1beta1.provisioner.PostgresResource + (*MysqlResource)(nil), // 2: xyz.block.ftl.v1beta1.provisioner.MysqlResource + (*MigrationResource)(nil), // 3: xyz.block.ftl.v1beta1.provisioner.MigrationResource + (*ModuleResource)(nil), // 4: xyz.block.ftl.v1beta1.provisioner.ModuleResource + (*PostgresResource_PostgresResourceOutput)(nil), // 5: xyz.block.ftl.v1beta1.provisioner.PostgresResource.PostgresResourceOutput + (*MysqlResource_MysqlResourceOutput)(nil), // 6: xyz.block.ftl.v1beta1.provisioner.MysqlResource.MysqlResourceOutput + (*MigrationResource_MigrationResourceOutput)(nil), // 7: xyz.block.ftl.v1beta1.provisioner.MigrationResource.MigrationResourceOutput + (*ModuleResource_ModuleResourceOutput)(nil), // 8: xyz.block.ftl.v1beta1.provisioner.ModuleResource.ModuleResourceOutput + (*schema.Module)(nil), // 9: xyz.block.ftl.v1.schema.Module + (*v1.DeploymentArtefact)(nil), // 10: xyz.block.ftl.v1.DeploymentArtefact + (*structpb.Struct)(nil), // 11: google.protobuf.Struct } var file_xyz_block_ftl_v1beta1_provisioner_resource_proto_depIdxs = []int32{ - 1, // 0: xyz.block.ftl.v1beta1.provisioner.Resource.postgres:type_name -> xyz.block.ftl.v1beta1.provisioner.PostgresResource - 2, // 1: xyz.block.ftl.v1beta1.provisioner.Resource.mysql:type_name -> xyz.block.ftl.v1beta1.provisioner.MysqlResource - 3, // 2: xyz.block.ftl.v1beta1.provisioner.Resource.module:type_name -> xyz.block.ftl.v1beta1.provisioner.ModuleResource - 4, // 3: xyz.block.ftl.v1beta1.provisioner.PostgresResource.output:type_name -> xyz.block.ftl.v1beta1.provisioner.PostgresResource.PostgresResourceOutput - 5, // 4: xyz.block.ftl.v1beta1.provisioner.MysqlResource.output:type_name -> xyz.block.ftl.v1beta1.provisioner.MysqlResource.MysqlResourceOutput - 6, // 5: xyz.block.ftl.v1beta1.provisioner.ModuleResource.output:type_name -> xyz.block.ftl.v1beta1.provisioner.ModuleResource.ModuleResourceOutput - 7, // 6: xyz.block.ftl.v1beta1.provisioner.ModuleResource.schema:type_name -> xyz.block.ftl.v1.schema.Module - 8, // 7: xyz.block.ftl.v1beta1.provisioner.ModuleResource.artefacts:type_name -> xyz.block.ftl.v1.DeploymentArtefact - 9, // 8: xyz.block.ftl.v1beta1.provisioner.ModuleResource.labels:type_name -> google.protobuf.Struct - 9, // [9:9] is the sub-list for method output_type - 9, // [9:9] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + 1, // 0: xyz.block.ftl.v1beta1.provisioner.Resource.postgres:type_name -> xyz.block.ftl.v1beta1.provisioner.PostgresResource + 2, // 1: xyz.block.ftl.v1beta1.provisioner.Resource.mysql:type_name -> xyz.block.ftl.v1beta1.provisioner.MysqlResource + 4, // 2: xyz.block.ftl.v1beta1.provisioner.Resource.module:type_name -> xyz.block.ftl.v1beta1.provisioner.ModuleResource + 3, // 3: xyz.block.ftl.v1beta1.provisioner.Resource.migration:type_name -> xyz.block.ftl.v1beta1.provisioner.MigrationResource + 5, // 4: xyz.block.ftl.v1beta1.provisioner.PostgresResource.output:type_name -> xyz.block.ftl.v1beta1.provisioner.PostgresResource.PostgresResourceOutput + 6, // 5: xyz.block.ftl.v1beta1.provisioner.MysqlResource.output:type_name -> xyz.block.ftl.v1beta1.provisioner.MysqlResource.MysqlResourceOutput + 7, // 6: xyz.block.ftl.v1beta1.provisioner.MigrationResource.output:type_name -> xyz.block.ftl.v1beta1.provisioner.MigrationResource.MigrationResourceOutput + 8, // 7: xyz.block.ftl.v1beta1.provisioner.ModuleResource.output:type_name -> xyz.block.ftl.v1beta1.provisioner.ModuleResource.ModuleResourceOutput + 9, // 8: xyz.block.ftl.v1beta1.provisioner.ModuleResource.schema:type_name -> xyz.block.ftl.v1.schema.Module + 10, // 9: xyz.block.ftl.v1beta1.provisioner.ModuleResource.artefacts:type_name -> xyz.block.ftl.v1.DeploymentArtefact + 11, // 10: xyz.block.ftl.v1beta1.provisioner.ModuleResource.labels:type_name -> google.protobuf.Struct + 11, // [11:11] is the sub-list for method output_type + 11, // [11:11] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_xyz_block_ftl_v1beta1_provisioner_resource_proto_init() } @@ -577,15 +701,16 @@ func file_xyz_block_ftl_v1beta1_provisioner_resource_proto_init() { (*Resource_Postgres)(nil), (*Resource_Mysql)(nil), (*Resource_Module)(nil), + (*Resource_Migration)(nil), } - file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[3].OneofWrappers = []any{} + file_xyz_block_ftl_v1beta1_provisioner_resource_proto_msgTypes[4].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_xyz_block_ftl_v1beta1_provisioner_resource_proto_rawDesc, NumEnums: 0, - NumMessages: 7, + NumMessages: 9, NumExtensions: 0, NumServices: 0, }, diff --git a/backend/protos/xyz/block/ftl/v1beta1/provisioner/resource.proto b/backend/protos/xyz/block/ftl/v1beta1/provisioner/resource.proto index 1e65d33a2..e27a91a88 100644 --- a/backend/protos/xyz/block/ftl/v1beta1/provisioner/resource.proto +++ b/backend/protos/xyz/block/ftl/v1beta1/provisioner/resource.proto @@ -18,6 +18,7 @@ message Resource { PostgresResource postgres = 102; MysqlResource mysql = 103; ModuleResource module = 104; + MigrationResource migration = 105; } } @@ -41,6 +42,12 @@ message MysqlResource { MysqlResourceOutput output = 1; } +message MigrationResource { + message MigrationResourceOutput {} + MigrationResourceOutput output = 1; + string digest = 2; +} + message ModuleResource { message ModuleResourceOutput { string deployment_key = 1; diff --git a/backend/provisioner/migration.go b/backend/provisioner/migration.go new file mode 100644 index 000000000..5c27ca5d0 --- /dev/null +++ b/backend/provisioner/migration.go @@ -0,0 +1,128 @@ +package provisioner + +import ( + "archive/tar" + "context" + "database/sql" + "fmt" + "io" + "net/url" + "os" + "path/filepath" + + "github.com/amacneil/dbmate/v2/pkg/dbmate" + _ "github.com/go-sql-driver/mysql" + + "github.com/TBD54566975/ftl/backend/controller/artefacts" + "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1beta1/provisioner" + "github.com/TBD54566975/ftl/internal/log" + "github.com/TBD54566975/ftl/internal/sha256" +) + +// NewMigrationProvisioner creates a new provisioner that provisions database migrations +func NewMigrationProvisioner(registryConfig artefacts.RegistryConfig) *InMemProvisioner { + return NewEmbeddedProvisioner(map[ResourceType]InMemResourceProvisionerFn{ + ResourceTypeMigration: provisionMigration(registryConfig), + }) +} + +func provisionMigration(registryConfig artefacts.RegistryConfig) func(ctx context.Context, rc *provisioner.ResourceContext, module, id string) (*provisioner.Resource, error) { + return func(ctx context.Context, rc *provisioner.ResourceContext, module, id string) (*provisioner.Resource, error) { + migration, ok := rc.Resource.Resource.(*provisioner.Resource_Migration) + if !ok { + return nil, fmt.Errorf("unexpected resource type: %T", rc.Resource.Resource) + } + if len(rc.Dependencies) != 1 { + return nil, fmt.Errorf("migrations must have exaclyt one dependency, found %v", rc.Dependencies) + } + registry, err := artefacts.NewOCIRegistryStorage(registryConfig) + if err != nil { + return nil, fmt.Errorf("failed to create OCI registry storage: %w", err) + } + parseSHA256, err := sha256.ParseSHA256(rc.Resource.GetMigration().Digest) + if err != nil { + return nil, fmt.Errorf("failed to parse digest %w", err) + } + download, err := registry.Download(ctx, parseSHA256) + if err != nil { + return nil, fmt.Errorf("failed to download migration: %w", err) + } + dir, err := extractTarToTempDir(download) + if err != nil { + return nil, fmt.Errorf("failed to extract tar: %w", err) + } + dsn := "" + driver := "" + + resource := rc.Dependencies[0].Resource + switch res := resource.(type) { + case *provisioner.Resource_Postgres: + dsn = res.Postgres.GetOutput().GetWriteDsn() + driver = "pgx" + case *provisioner.Resource_Mysql: + dsn = res.Mysql.GetOutput().GetWriteDsn() + driver = "mysql" + } + u, err := url.Parse(dsn) + if err != nil { + return nil, fmt.Errorf("invalid DSN: %w", err) + } + + conn, err := sql.Open(driver, dsn) + if err != nil { + return nil, fmt.Errorf("failed to connect to database: %w", err) + } + defer conn.Close() + + db := dbmate.New(u) + db.AutoDumpSchema = false + db.Log = log.FromContext(ctx).Scope("migrate").WriterAt(log.Info) + db.MigrationsDir = []string{dir} + err = db.CreateAndMigrate() + if err != nil { + return nil, fmt.Errorf("failed to create and migrate database: %w", err) + } + migration.Migration = &provisioner.MigrationResource{ + Output: &provisioner.MigrationResource_MigrationResourceOutput{}, + } + return rc.Resource, nil + } +} + +func extractTarToTempDir(tarReader io.Reader) (tempDir string, err error) { + // Create a new tar reader + tr := tar.NewReader(tarReader) + + // Create a temporary directory + tempDir, err = os.MkdirTemp("", "extracted") + if err != nil { + return "", fmt.Errorf("failed to create temporary directory: %w", err) + } + + // Extract files from the tar archive + for { + header, err := tr.Next() + if err == io.EOF { + break // End of tar archive + } + if err != nil { + return "", fmt.Errorf("failed to read tar header: %w", err) + } + + // Construct the full path for the file + targetPath := filepath.Join(tempDir, header.Name) + + // Create the file + file, err := os.OpenFile(targetPath, os.O_CREATE|os.O_WRONLY, os.FileMode(header.Mode)) + if err != nil { + return "", fmt.Errorf("failed to create file: %w", err) + } + defer file.Close() + + // Copy the file content + if _, err := io.Copy(file, tr); err != nil { + return "", fmt.Errorf("failed to copy file content: %w", err) + } + } + return tempDir, nil +} diff --git a/backend/provisioner/registry.go b/backend/provisioner/registry.go index 3f8583fe7..814297737 100644 --- a/backend/provisioner/registry.go +++ b/backend/provisioner/registry.go @@ -189,6 +189,7 @@ func resourceEqual(desired, existing *provisioner.Resource) bool { &provisioner.MysqlResource_MysqlResourceOutput{}, &provisioner.PostgresResource_PostgresResourceOutput{}, &provisioner.ModuleResource_ModuleResourceOutput{}, + &provisioner.MigrationResource_MigrationResourceOutput{}, ), ) } @@ -201,6 +202,7 @@ func ExtractResources(msg *ftlv1.CreateDeploymentRequest) (*ResourceGraph, error if err != nil { return nil, fmt.Errorf("invalid module schema for module %s: %w", msg.Schema.Name, err) } + edges := make([]*ResourceEdge, 0) for _, decl := range module.Decls { if db, ok := decl.(*schema.Database); ok { @@ -218,6 +220,20 @@ func ExtractResources(msg *ftlv1.CreateDeploymentRequest) (*ResourceGraph, error default: return nil, fmt.Errorf("unknown db type: %s", db.Type) } + for _, metadata := range db.Metadata { + if migration, ok := metadata.(*schema.MetadataMigration); ok { + id := decl.GetName() + "-migration-" + migration.Digest + deps = append(deps, &provisioner.Resource{ + ResourceId: id, + Resource: &provisioner.Resource_Migration{Migration: &provisioner.MigrationResource{Digest: migration.Digest}}, + }) + edges = append(edges, &ResourceEdge{ + from: id, + to: decl.GetName(), + }) + } + + } } } @@ -231,12 +247,11 @@ func ExtractResources(msg *ftlv1.CreateDeploymentRequest) (*ResourceGraph, error }, }, } - edges := make([]*ResourceEdge, len(deps)) - for i, dep := range deps { - edges[i] = &ResourceEdge{ + for _, dep := range deps { + edges = append(edges, &ResourceEdge{ from: root.ResourceId, to: dep.ResourceId, - } + }) } result := &ResourceGraph{ diff --git a/backend/provisioner/resource_type.go b/backend/provisioner/resource_type.go index bb49693e2..319e3a966 100644 --- a/backend/provisioner/resource_type.go +++ b/backend/provisioner/resource_type.go @@ -8,10 +8,11 @@ import ( type ResourceType string const ( - ResourceTypeUnknown ResourceType = "unknown" - ResourceTypePostgres ResourceType = "postgres" - ResourceTypeMysql ResourceType = "mysql" - ResourceTypeModule ResourceType = "module" + ResourceTypeUnknown ResourceType = "unknown" + ResourceTypePostgres ResourceType = "postgres" + ResourceTypeMysql ResourceType = "mysql" + ResourceTypeModule ResourceType = "module" + ResourceTypeMigration ResourceType = "migration" ) // TypeOf returns the resource type of the given resource @@ -23,6 +24,8 @@ func TypeOf(r *provisioner.Resource) ResourceType { return ResourceTypeMysql case *provisioner.Resource_Postgres: return ResourceTypePostgres + case *provisioner.Resource_Migration: + return ResourceTypeMigration default: return ResourceTypeUnknown } diff --git a/frontend/cli/cmd_serve.go b/frontend/cli/cmd_serve.go index e1eb0ddd4..c47367cb0 100644 --- a/frontend/cli/cmd_serve.go +++ b/frontend/cli/cmd_serve.go @@ -243,12 +243,19 @@ func (s *serveCommonConfig) run( provisionerCtx := log.ContextWithLogger(ctx, logger.Scope(scope)) // default local dev provisioner - registry := &provisioner.ProvisionerRegistry{ - Provisioners: []*provisioner.ProvisionerBinding{{ - Provisioner: provisioner.NewControllerProvisioner(controllerClient), - Types: []provisioner.ResourceType{provisioner.ResourceTypeModule}, - ID: "controller", - }}, + provisionerRegistry := &provisioner.ProvisionerRegistry{ + Provisioners: []*provisioner.ProvisionerBinding{ + { + Provisioner: provisioner.NewControllerProvisioner(controllerClient), + Types: []provisioner.ResourceType{provisioner.ResourceTypeModule}, + ID: "controller", + }, + { + Provisioner: provisioner.NewMigrationProvisioner(registry), + Types: []provisioner.ResourceType{provisioner.ResourceTypeMigration}, + ID: "migration", + }, + }, Default: &provisioner.ProvisionerBinding{ Provisioner: provisioner.NewDevProvisioner(s.DBPort, s.MysqlPort), ID: "dev", @@ -261,11 +268,11 @@ func (s *serveCommonConfig) run( if err != nil { return fmt.Errorf("failed to create provisioner registry: %w", err) } - registry = r + provisionerRegistry = r } wg.Go(func() error { - if err := provisioner.Start(provisionerCtx, config, registry, controllerClient, schemaClient); err != nil { + if err := provisioner.Start(provisionerCtx, config, provisionerRegistry, controllerClient, schemaClient); err != nil { logger.Errorf(err, "provisioner%d failed: %v", i, err) return fmt.Errorf("provisioner%d failed: %w", i, err) } diff --git a/frontend/console/src/protos/xyz/block/ftl/v1beta1/provisioner/resource_pb.ts b/frontend/console/src/protos/xyz/block/ftl/v1beta1/provisioner/resource_pb.ts index 9d6981c5f..b3e421052 100644 --- a/frontend/console/src/protos/xyz/block/ftl/v1beta1/provisioner/resource_pb.ts +++ b/frontend/console/src/protos/xyz/block/ftl/v1beta1/provisioner/resource_pb.ts @@ -42,6 +42,12 @@ export class Resource extends Message { */ value: ModuleResource; case: "module"; + } | { + /** + * @generated from field: xyz.block.ftl.v1beta1.provisioner.MigrationResource migration = 105; + */ + value: MigrationResource; + case: "migration"; } | { case: undefined; value?: undefined } = { case: undefined }; constructor(data?: PartialMessage) { @@ -56,6 +62,7 @@ export class Resource extends Message { { no: 102, name: "postgres", kind: "message", T: PostgresResource, oneof: "resource" }, { no: 103, name: "mysql", kind: "message", T: MysqlResource, oneof: "resource" }, { no: 104, name: "module", kind: "message", T: ModuleResource, oneof: "resource" }, + { no: 105, name: "migration", kind: "message", T: MigrationResource, oneof: "resource" }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): Resource { @@ -235,6 +242,80 @@ export class MysqlResource_MysqlResourceOutput extends Message { + /** + * @generated from field: xyz.block.ftl.v1beta1.provisioner.MigrationResource.MigrationResourceOutput output = 1; + */ + output?: MigrationResource_MigrationResourceOutput; + + /** + * @generated from field: string digest = 2; + */ + digest = ""; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.v1beta1.provisioner.MigrationResource"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "output", kind: "message", T: MigrationResource_MigrationResourceOutput }, + { no: 2, name: "digest", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): MigrationResource { + return new MigrationResource().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): MigrationResource { + return new MigrationResource().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): MigrationResource { + return new MigrationResource().fromJsonString(jsonString, options); + } + + static equals(a: MigrationResource | PlainMessage | undefined, b: MigrationResource | PlainMessage | undefined): boolean { + return proto3.util.equals(MigrationResource, a, b); + } +} + +/** + * @generated from message xyz.block.ftl.v1beta1.provisioner.MigrationResource.MigrationResourceOutput + */ +export class MigrationResource_MigrationResourceOutput extends Message { + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.v1beta1.provisioner.MigrationResource.MigrationResourceOutput"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): MigrationResource_MigrationResourceOutput { + return new MigrationResource_MigrationResourceOutput().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): MigrationResource_MigrationResourceOutput { + return new MigrationResource_MigrationResourceOutput().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): MigrationResource_MigrationResourceOutput { + return new MigrationResource_MigrationResourceOutput().fromJsonString(jsonString, options); + } + + static equals(a: MigrationResource_MigrationResourceOutput | PlainMessage | undefined, b: MigrationResource_MigrationResourceOutput | PlainMessage | undefined): boolean { + return proto3.util.equals(MigrationResource_MigrationResourceOutput, a, b); + } +} + /** * @generated from message xyz.block.ftl.v1beta1.provisioner.ModuleResource */ diff --git a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1beta1/provisioner/resource_pb2.py b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1beta1/provisioner/resource_pb2.py index bc505280f..90444f548 100644 --- a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1beta1/provisioner/resource_pb2.py +++ b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1beta1/provisioner/resource_pb2.py @@ -27,7 +27,7 @@ from xyz.block.ftl.v1.schema import schema_pb2 as xyz_dot_block_dot_ftl_dot_v1_dot_schema_dot_schema__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n0xyz/block/ftl/v1beta1/provisioner/resource.proto\x12!xyz.block.ftl.v1beta1.provisioner\x1a\x1cgoogle/protobuf/struct.proto\x1a!xyz/block/ftl/v1/controller.proto\x1a$xyz/block/ftl/v1/schema/schema.proto\"\xa1\x02\n\x08Resource\x12\x1f\n\x0bresource_id\x18\x01 \x01(\tR\nresourceId\x12Q\n\x08postgres\x18\x66 \x01(\x0b\x32\x33.xyz.block.ftl.v1beta1.provisioner.PostgresResourceH\x00R\x08postgres\x12H\n\x05mysql\x18g \x01(\x0b\x32\x30.xyz.block.ftl.v1beta1.provisioner.MysqlResourceH\x00R\x05mysql\x12K\n\x06module\x18h \x01(\x0b\x32\x31.xyz.block.ftl.v1beta1.provisioner.ModuleResourceH\x00R\x06moduleB\n\n\x08resource\"\xc8\x01\n\x10PostgresResource\x12\x62\n\x06output\x18\x01 \x01(\x0b\x32J.xyz.block.ftl.v1beta1.provisioner.PostgresResource.PostgresResourceOutputR\x06output\x1aP\n\x16PostgresResourceOutput\x12\x19\n\x08read_dsn\x18\x01 \x01(\tR\x07readDsn\x12\x1b\n\twrite_dsn\x18\x02 \x01(\tR\x08writeDsn\"\xbc\x01\n\rMysqlResource\x12\\\n\x06output\x18\x01 \x01(\x0b\x32\x44.xyz.block.ftl.v1beta1.provisioner.MysqlResource.MysqlResourceOutputR\x06output\x1aM\n\x13MysqlResourceOutput\x12\x19\n\x08read_dsn\x18\x01 \x01(\tR\x07readDsn\x12\x1b\n\twrite_dsn\x18\x02 \x01(\tR\x08writeDsn\"\xed\x02\n\x0eModuleResource\x12^\n\x06output\x18\x01 \x01(\x0b\x32\x46.xyz.block.ftl.v1beta1.provisioner.ModuleResource.ModuleResourceOutputR\x06output\x12\x37\n\x06schema\x18\x02 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.ModuleR\x06schema\x12\x42\n\tartefacts\x18\x03 \x03(\x0b\x32$.xyz.block.ftl.v1.DeploymentArtefactR\tartefacts\x12\x34\n\x06labels\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructH\x00R\x06labels\x88\x01\x01\x1a=\n\x14ModuleResourceOutput\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKeyB\t\n\x07_labelsB[P\x01ZWgithub.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1beta1/provisioner;provisionerb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n0xyz/block/ftl/v1beta1/provisioner/resource.proto\x12!xyz.block.ftl.v1beta1.provisioner\x1a\x1cgoogle/protobuf/struct.proto\x1a!xyz/block/ftl/v1/controller.proto\x1a$xyz/block/ftl/v1/schema/schema.proto\"\xf7\x02\n\x08Resource\x12\x1f\n\x0bresource_id\x18\x01 \x01(\tR\nresourceId\x12Q\n\x08postgres\x18\x66 \x01(\x0b\x32\x33.xyz.block.ftl.v1beta1.provisioner.PostgresResourceH\x00R\x08postgres\x12H\n\x05mysql\x18g \x01(\x0b\x32\x30.xyz.block.ftl.v1beta1.provisioner.MysqlResourceH\x00R\x05mysql\x12K\n\x06module\x18h \x01(\x0b\x32\x31.xyz.block.ftl.v1beta1.provisioner.ModuleResourceH\x00R\x06module\x12T\n\tmigration\x18i \x01(\x0b\x32\x34.xyz.block.ftl.v1beta1.provisioner.MigrationResourceH\x00R\tmigrationB\n\n\x08resource\"\xc8\x01\n\x10PostgresResource\x12\x62\n\x06output\x18\x01 \x01(\x0b\x32J.xyz.block.ftl.v1beta1.provisioner.PostgresResource.PostgresResourceOutputR\x06output\x1aP\n\x16PostgresResourceOutput\x12\x19\n\x08read_dsn\x18\x01 \x01(\tR\x07readDsn\x12\x1b\n\twrite_dsn\x18\x02 \x01(\tR\x08writeDsn\"\xbc\x01\n\rMysqlResource\x12\\\n\x06output\x18\x01 \x01(\x0b\x32\x44.xyz.block.ftl.v1beta1.provisioner.MysqlResource.MysqlResourceOutputR\x06output\x1aM\n\x13MysqlResourceOutput\x12\x19\n\x08read_dsn\x18\x01 \x01(\tR\x07readDsn\x12\x1b\n\twrite_dsn\x18\x02 \x01(\tR\x08writeDsn\"\xac\x01\n\x11MigrationResource\x12\x64\n\x06output\x18\x01 \x01(\x0b\x32L.xyz.block.ftl.v1beta1.provisioner.MigrationResource.MigrationResourceOutputR\x06output\x12\x16\n\x06\x64igest\x18\x02 \x01(\tR\x06\x64igest\x1a\x19\n\x17MigrationResourceOutput\"\xed\x02\n\x0eModuleResource\x12^\n\x06output\x18\x01 \x01(\x0b\x32\x46.xyz.block.ftl.v1beta1.provisioner.ModuleResource.ModuleResourceOutputR\x06output\x12\x37\n\x06schema\x18\x02 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.ModuleR\x06schema\x12\x42\n\tartefacts\x18\x03 \x03(\x0b\x32$.xyz.block.ftl.v1.DeploymentArtefactR\tartefacts\x12\x34\n\x06labels\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructH\x00R\x06labels\x88\x01\x01\x1a=\n\x14ModuleResourceOutput\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKeyB\t\n\x07_labelsB[P\x01ZWgithub.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1beta1/provisioner;provisionerb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -36,17 +36,21 @@ _globals['DESCRIPTOR']._loaded_options = None _globals['DESCRIPTOR']._serialized_options = b'P\001ZWgithub.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1beta1/provisioner;provisioner' _globals['_RESOURCE']._serialized_start=191 - _globals['_RESOURCE']._serialized_end=480 - _globals['_POSTGRESRESOURCE']._serialized_start=483 - _globals['_POSTGRESRESOURCE']._serialized_end=683 - _globals['_POSTGRESRESOURCE_POSTGRESRESOURCEOUTPUT']._serialized_start=603 - _globals['_POSTGRESRESOURCE_POSTGRESRESOURCEOUTPUT']._serialized_end=683 - _globals['_MYSQLRESOURCE']._serialized_start=686 - _globals['_MYSQLRESOURCE']._serialized_end=874 - _globals['_MYSQLRESOURCE_MYSQLRESOURCEOUTPUT']._serialized_start=797 - _globals['_MYSQLRESOURCE_MYSQLRESOURCEOUTPUT']._serialized_end=874 - _globals['_MODULERESOURCE']._serialized_start=877 - _globals['_MODULERESOURCE']._serialized_end=1242 - _globals['_MODULERESOURCE_MODULERESOURCEOUTPUT']._serialized_start=1170 - _globals['_MODULERESOURCE_MODULERESOURCEOUTPUT']._serialized_end=1231 + _globals['_RESOURCE']._serialized_end=566 + _globals['_POSTGRESRESOURCE']._serialized_start=569 + _globals['_POSTGRESRESOURCE']._serialized_end=769 + _globals['_POSTGRESRESOURCE_POSTGRESRESOURCEOUTPUT']._serialized_start=689 + _globals['_POSTGRESRESOURCE_POSTGRESRESOURCEOUTPUT']._serialized_end=769 + _globals['_MYSQLRESOURCE']._serialized_start=772 + _globals['_MYSQLRESOURCE']._serialized_end=960 + _globals['_MYSQLRESOURCE_MYSQLRESOURCEOUTPUT']._serialized_start=883 + _globals['_MYSQLRESOURCE_MYSQLRESOURCEOUTPUT']._serialized_end=960 + _globals['_MIGRATIONRESOURCE']._serialized_start=963 + _globals['_MIGRATIONRESOURCE']._serialized_end=1135 + _globals['_MIGRATIONRESOURCE_MIGRATIONRESOURCEOUTPUT']._serialized_start=1110 + _globals['_MIGRATIONRESOURCE_MIGRATIONRESOURCEOUTPUT']._serialized_end=1135 + _globals['_MODULERESOURCE']._serialized_start=1138 + _globals['_MODULERESOURCE']._serialized_end=1503 + _globals['_MODULERESOURCE_MODULERESOURCEOUTPUT']._serialized_start=1431 + _globals['_MODULERESOURCE_MODULERESOURCEOUTPUT']._serialized_end=1492 # @@protoc_insertion_point(module_scope) diff --git a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1beta1/provisioner/resource_pb2.pyi b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1beta1/provisioner/resource_pb2.pyi index 75c298e66..1c2dc6174 100644 --- a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1beta1/provisioner/resource_pb2.pyi +++ b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1beta1/provisioner/resource_pb2.pyi @@ -9,16 +9,18 @@ from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Map DESCRIPTOR: _descriptor.FileDescriptor class Resource(_message.Message): - __slots__ = ("resource_id", "postgres", "mysql", "module") + __slots__ = ("resource_id", "postgres", "mysql", "module", "migration") RESOURCE_ID_FIELD_NUMBER: _ClassVar[int] POSTGRES_FIELD_NUMBER: _ClassVar[int] MYSQL_FIELD_NUMBER: _ClassVar[int] MODULE_FIELD_NUMBER: _ClassVar[int] + MIGRATION_FIELD_NUMBER: _ClassVar[int] resource_id: str postgres: PostgresResource mysql: MysqlResource module: ModuleResource - def __init__(self, resource_id: _Optional[str] = ..., postgres: _Optional[_Union[PostgresResource, _Mapping]] = ..., mysql: _Optional[_Union[MysqlResource, _Mapping]] = ..., module: _Optional[_Union[ModuleResource, _Mapping]] = ...) -> None: ... + migration: MigrationResource + def __init__(self, resource_id: _Optional[str] = ..., postgres: _Optional[_Union[PostgresResource, _Mapping]] = ..., mysql: _Optional[_Union[MysqlResource, _Mapping]] = ..., module: _Optional[_Union[ModuleResource, _Mapping]] = ..., migration: _Optional[_Union[MigrationResource, _Mapping]] = ...) -> None: ... class PostgresResource(_message.Message): __slots__ = ("output",) @@ -46,6 +48,17 @@ class MysqlResource(_message.Message): output: MysqlResource.MysqlResourceOutput def __init__(self, output: _Optional[_Union[MysqlResource.MysqlResourceOutput, _Mapping]] = ...) -> None: ... +class MigrationResource(_message.Message): + __slots__ = ("output", "digest") + class MigrationResourceOutput(_message.Message): + __slots__ = () + def __init__(self) -> None: ... + OUTPUT_FIELD_NUMBER: _ClassVar[int] + DIGEST_FIELD_NUMBER: _ClassVar[int] + output: MigrationResource.MigrationResourceOutput + digest: str + def __init__(self, output: _Optional[_Union[MigrationResource.MigrationResourceOutput, _Mapping]] = ..., digest: _Optional[str] = ...) -> None: ... + class ModuleResource(_message.Message): __slots__ = ("output", "schema", "artefacts", "labels") class ModuleResourceOutput(_message.Message):