diff --git a/internal/api/osac/private/v1/event_type.pb.go b/internal/api/osac/private/v1/event_type.pb.go index f896f518d..abb9a3484 100644 --- a/internal/api/osac/private/v1/event_type.pb.go +++ b/internal/api/osac/private/v1/event_type.pb.go @@ -121,6 +121,7 @@ type Event struct { // *Event_SecurityGroup // *Event_Lease // *Event_PublicIpPool + // *Event_PublicIp Payload isEvent_Payload `protobuf_oneof:"payload"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -280,6 +281,15 @@ func (x *Event) GetPublicIpPool() *PublicIPPool { return nil } +func (x *Event) GetPublicIp() *PublicIP { + if x != nil { + if x, ok := x.Payload.(*Event_PublicIp); ok { + return x.PublicIp + } + } + return nil +} + func (x *Event) SetId(v string) { x.Id = v } @@ -384,6 +394,14 @@ func (x *Event) SetPublicIpPool(v *PublicIPPool) { x.Payload = &Event_PublicIpPool{v} } +func (x *Event) SetPublicIp(v *PublicIP) { + if v == nil { + x.Payload = nil + return + } + x.Payload = &Event_PublicIp{v} +} + func (x *Event) HasPayload() bool { if x == nil { return false @@ -487,6 +505,14 @@ func (x *Event) HasPublicIpPool() bool { return ok } +func (x *Event) HasPublicIp() bool { + if x == nil { + return false + } + _, ok := x.Payload.(*Event_PublicIp) + return ok +} + func (x *Event) ClearPayload() { x.Payload = nil } @@ -563,6 +589,12 @@ func (x *Event) ClearPublicIpPool() { } } +func (x *Event) ClearPublicIp() { + if _, ok := x.Payload.(*Event_PublicIp); ok { + x.Payload = nil + } +} + const Event_Payload_not_set_case case_Event_Payload = 0 const Event_Cluster_case case_Event_Payload = 3 const Event_ClusterTemplate_case case_Event_Payload = 4 @@ -576,6 +608,7 @@ const Event_VirtualNetwork_case case_Event_Payload = 13 const Event_SecurityGroup_case case_Event_Payload = 14 const Event_Lease_case case_Event_Payload = 15 const Event_PublicIpPool_case case_Event_Payload = 16 +const Event_PublicIp_case case_Event_Payload = 17 func (x *Event) WhichPayload() case_Event_Payload { if x == nil { @@ -606,6 +639,8 @@ func (x *Event) WhichPayload() case_Event_Payload { return Event_Lease_case case *Event_PublicIpPool: return Event_PublicIpPool_case + case *Event_PublicIp: + return Event_PublicIp_case default: return Event_Payload_not_set_case } @@ -633,6 +668,7 @@ type Event_builder struct { SecurityGroup *SecurityGroup Lease *Lease PublicIpPool *PublicIPPool + PublicIp *PublicIP // -- end of Payload } @@ -678,6 +714,9 @@ func (b0 Event_builder) Build() *Event { if b.PublicIpPool != nil { x.Payload = &Event_PublicIpPool{b.PublicIpPool} } + if b.PublicIp != nil { + x.Payload = &Event_PublicIp{b.PublicIp} + } return m0 } @@ -743,6 +782,10 @@ type Event_PublicIpPool struct { PublicIpPool *PublicIPPool `protobuf:"bytes,16,opt,name=public_ip_pool,json=publicIpPool,proto3,oneof"` } +type Event_PublicIp struct { + PublicIp *PublicIP `protobuf:"bytes,17,opt,name=public_ip,json=publicIp,proto3,oneof"` +} + func (*Event_Cluster) isEvent_Payload() {} func (*Event_ClusterTemplate) isEvent_Payload() {} @@ -767,6 +810,8 @@ func (*Event_Lease) isEvent_Payload() {} func (*Event_PublicIpPool) isEvent_Payload() {} +func (*Event_PublicIp) isEvent_Payload() {} + var File_osac_private_v1_event_type_proto protoreflect.FileDescriptor var file_osac_private_v1_event_type_proto_rawDesc = string([]byte{ @@ -796,69 +841,75 @@ var file_osac_private_v1_event_type_proto_rawDesc = string([]byte{ 0x79, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x6f, 0x73, 0x61, 0x63, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x6f, 0x73, 0x61, 0x63, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x21, 0x6f, 0x73, 0x61, 0x63, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, - 0x2f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x2a, 0x6f, 0x73, 0x61, 0x63, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, - 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf7, - 0x06, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, - 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6f, 0x73, 0x61, 0x63, - 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x4d, - 0x0a, 0x10, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, - 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, - 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x38, 0x0a, - 0x09, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x08, 0x68, - 0x6f, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x03, 0x68, 0x75, 0x62, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x75, 0x62, 0x48, 0x00, 0x52, 0x03, 0x68, 0x75, - 0x62, 0x12, 0x66, 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x48, 0x00, - 0x52, 0x17, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x4d, 0x0a, 0x10, 0x63, 0x6f, 0x6d, - 0x70, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1d, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x48, 0x00, - 0x52, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x31, - 0x0a, 0x06, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x48, 0x00, 0x52, 0x06, 0x73, 0x75, 0x62, 0x6e, 0x65, - 0x74, 0x12, 0x4a, 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x6e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x73, 0x61, - 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x69, 0x72, - 0x74, 0x75, 0x61, 0x6c, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x48, 0x00, 0x52, 0x0e, 0x76, - 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x47, 0x0a, - 0x0e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, - 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, - 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x0d, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, - 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2e, 0x0a, 0x05, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, - 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, - 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x48, 0x00, 0x52, - 0x05, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x6f, 0x73, 0x61, 0x63, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x69, 0x70, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x6f, 0x73, 0x61, 0x63, + 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x75, + 0x72, 0x69, 0x74, 0x79, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x6f, 0x73, 0x61, 0x63, 0x2f, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x6f, 0x73, 0x61, 0x63, 0x2f, 0x70, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, + 0x6c, 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb1, 0x07, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2e, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x6f, + 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x34, + 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x10, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x50, 0x50, 0x6f, 0x6f, 0x6c, 0x48, 0x00, 0x52, - 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x70, 0x50, 0x6f, 0x6f, 0x6c, 0x42, 0x09, 0x0a, + 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x48, 0x00, 0x52, 0x0f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x48, 0x00, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, + 0x03, 0x68, 0x75, 0x62, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x73, 0x61, + 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x75, 0x62, + 0x48, 0x00, 0x52, 0x03, 0x68, 0x75, 0x62, 0x12, 0x66, 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x70, 0x75, + 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6f, 0x73, 0x61, + 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, + 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x17, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, + 0x4d, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f, 0x73, 0x61, 0x63, + 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, + 0x75, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x63, + 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x44, + 0x0a, 0x0d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x12, 0x31, 0x0a, 0x06, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x48, 0x00, 0x52, + 0x06, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x12, 0x4a, 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, + 0x61, 0x6c, 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x48, 0x00, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x12, 0x47, 0x0a, 0x0e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6f, 0x73, + 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, + 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x0d, 0x73, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2e, 0x0a, 0x05, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6f, 0x73, + 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x65, + 0x61, 0x73, 0x65, 0x48, 0x00, 0x52, 0x05, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0e, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x18, 0x10, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x50, 0x50, + 0x6f, 0x6f, 0x6c, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x70, 0x50, + 0x6f, 0x6f, 0x6c, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x69, 0x70, + 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, + 0x50, 0x48, 0x00, 0x52, 0x08, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x70, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2a, 0xa4, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, @@ -904,6 +955,7 @@ var file_osac_private_v1_event_type_proto_goTypes = []any{ (*SecurityGroup)(nil), // 11: osac.private.v1.SecurityGroup (*Lease)(nil), // 12: osac.private.v1.Lease (*PublicIPPool)(nil), // 13: osac.private.v1.PublicIPPool + (*PublicIP)(nil), // 14: osac.private.v1.PublicIP } var file_osac_private_v1_event_type_proto_depIdxs = []int32{ 0, // 0: osac.private.v1.Event.type:type_name -> osac.private.v1.EventType @@ -919,11 +971,12 @@ var file_osac_private_v1_event_type_proto_depIdxs = []int32{ 11, // 10: osac.private.v1.Event.security_group:type_name -> osac.private.v1.SecurityGroup 12, // 11: osac.private.v1.Event.lease:type_name -> osac.private.v1.Lease 13, // 12: osac.private.v1.Event.public_ip_pool:type_name -> osac.private.v1.PublicIPPool - 13, // [13:13] is the sub-list for method output_type - 13, // [13:13] is the sub-list for method input_type - 13, // [13:13] is the sub-list for extension type_name - 13, // [13:13] is the sub-list for extension extendee - 0, // [0:13] is the sub-list for field type_name + 14, // 13: osac.private.v1.Event.public_ip:type_name -> osac.private.v1.PublicIP + 14, // [14:14] is the sub-list for method output_type + 14, // [14:14] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name } func init() { file_osac_private_v1_event_type_proto_init() } @@ -940,6 +993,7 @@ func file_osac_private_v1_event_type_proto_init() { file_osac_private_v1_lease_type_proto_init() file_osac_private_v1_network_class_type_proto_init() file_osac_private_v1_public_ip_pool_type_proto_init() + file_osac_private_v1_public_ip_type_proto_init() file_osac_private_v1_security_group_type_proto_init() file_osac_private_v1_subnet_type_proto_init() file_osac_private_v1_virtual_network_type_proto_init() @@ -956,6 +1010,7 @@ func file_osac_private_v1_event_type_proto_init() { (*Event_SecurityGroup)(nil), (*Event_Lease)(nil), (*Event_PublicIpPool)(nil), + (*Event_PublicIp)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/internal/api/osac/private/v1/event_type_protoopaque.pb.go b/internal/api/osac/private/v1/event_type_protoopaque.pb.go index c3339e00e..f539ef164 100644 --- a/internal/api/osac/private/v1/event_type_protoopaque.pb.go +++ b/internal/api/osac/private/v1/event_type_protoopaque.pb.go @@ -255,6 +255,15 @@ func (x *Event) GetPublicIpPool() *PublicIPPool { return nil } +func (x *Event) GetPublicIp() *PublicIP { + if x != nil { + if x, ok := x.xxx_hidden_Payload.(*event_PublicIp); ok { + return x.PublicIp + } + } + return nil +} + func (x *Event) SetId(v string) { x.xxx_hidden_Id = v } @@ -359,6 +368,14 @@ func (x *Event) SetPublicIpPool(v *PublicIPPool) { x.xxx_hidden_Payload = &event_PublicIpPool{v} } +func (x *Event) SetPublicIp(v *PublicIP) { + if v == nil { + x.xxx_hidden_Payload = nil + return + } + x.xxx_hidden_Payload = &event_PublicIp{v} +} + func (x *Event) HasPayload() bool { if x == nil { return false @@ -462,6 +479,14 @@ func (x *Event) HasPublicIpPool() bool { return ok } +func (x *Event) HasPublicIp() bool { + if x == nil { + return false + } + _, ok := x.xxx_hidden_Payload.(*event_PublicIp) + return ok +} + func (x *Event) ClearPayload() { x.xxx_hidden_Payload = nil } @@ -538,6 +563,12 @@ func (x *Event) ClearPublicIpPool() { } } +func (x *Event) ClearPublicIp() { + if _, ok := x.xxx_hidden_Payload.(*event_PublicIp); ok { + x.xxx_hidden_Payload = nil + } +} + const Event_Payload_not_set_case case_Event_Payload = 0 const Event_Cluster_case case_Event_Payload = 3 const Event_ClusterTemplate_case case_Event_Payload = 4 @@ -551,6 +582,7 @@ const Event_VirtualNetwork_case case_Event_Payload = 13 const Event_SecurityGroup_case case_Event_Payload = 14 const Event_Lease_case case_Event_Payload = 15 const Event_PublicIpPool_case case_Event_Payload = 16 +const Event_PublicIp_case case_Event_Payload = 17 func (x *Event) WhichPayload() case_Event_Payload { if x == nil { @@ -581,6 +613,8 @@ func (x *Event) WhichPayload() case_Event_Payload { return Event_Lease_case case *event_PublicIpPool: return Event_PublicIpPool_case + case *event_PublicIp: + return Event_PublicIp_case default: return Event_Payload_not_set_case } @@ -608,6 +642,7 @@ type Event_builder struct { SecurityGroup *SecurityGroup Lease *Lease PublicIpPool *PublicIPPool + PublicIp *PublicIP // -- end of xxx_hidden_Payload } @@ -653,6 +688,9 @@ func (b0 Event_builder) Build() *Event { if b.PublicIpPool != nil { x.xxx_hidden_Payload = &event_PublicIpPool{b.PublicIpPool} } + if b.PublicIp != nil { + x.xxx_hidden_Payload = &event_PublicIp{b.PublicIp} + } return m0 } @@ -718,6 +756,10 @@ type event_PublicIpPool struct { PublicIpPool *PublicIPPool `protobuf:"bytes,16,opt,name=public_ip_pool,json=publicIpPool,proto3,oneof"` } +type event_PublicIp struct { + PublicIp *PublicIP `protobuf:"bytes,17,opt,name=public_ip,json=publicIp,proto3,oneof"` +} + func (*event_Cluster) isEvent_Payload() {} func (*event_ClusterTemplate) isEvent_Payload() {} @@ -742,6 +784,8 @@ func (*event_Lease) isEvent_Payload() {} func (*event_PublicIpPool) isEvent_Payload() {} +func (*event_PublicIp) isEvent_Payload() {} + var File_osac_private_v1_event_type_proto protoreflect.FileDescriptor var file_osac_private_v1_event_type_proto_rawDesc = string([]byte{ @@ -771,69 +815,75 @@ var file_osac_private_v1_event_type_proto_rawDesc = string([]byte{ 0x79, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x6f, 0x73, 0x61, 0x63, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x6f, 0x73, 0x61, 0x63, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x21, 0x6f, 0x73, 0x61, 0x63, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, - 0x2f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x2a, 0x6f, 0x73, 0x61, 0x63, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, - 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf7, - 0x06, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, - 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6f, 0x73, 0x61, 0x63, - 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x4d, - 0x0a, 0x10, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, - 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, - 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x38, 0x0a, - 0x09, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x08, 0x68, - 0x6f, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x03, 0x68, 0x75, 0x62, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x75, 0x62, 0x48, 0x00, 0x52, 0x03, 0x68, 0x75, - 0x62, 0x12, 0x66, 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x48, 0x00, - 0x52, 0x17, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x4d, 0x0a, 0x10, 0x63, 0x6f, 0x6d, - 0x70, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1d, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x48, 0x00, - 0x52, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x31, - 0x0a, 0x06, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x48, 0x00, 0x52, 0x06, 0x73, 0x75, 0x62, 0x6e, 0x65, - 0x74, 0x12, 0x4a, 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x6e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x73, 0x61, - 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x69, 0x72, - 0x74, 0x75, 0x61, 0x6c, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x48, 0x00, 0x52, 0x0e, 0x76, - 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x47, 0x0a, - 0x0e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, - 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, - 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x0d, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, - 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2e, 0x0a, 0x05, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, - 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, - 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x48, 0x00, 0x52, - 0x05, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x6f, 0x73, 0x61, 0x63, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x69, 0x70, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x6f, 0x73, 0x61, 0x63, + 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x75, + 0x72, 0x69, 0x74, 0x79, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x6f, 0x73, 0x61, 0x63, 0x2f, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x6f, 0x73, 0x61, 0x63, 0x2f, 0x70, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, + 0x6c, 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb1, 0x07, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2e, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x6f, + 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x34, + 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x10, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x50, 0x50, 0x6f, 0x6f, 0x6c, 0x48, 0x00, 0x52, - 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x70, 0x50, 0x6f, 0x6f, 0x6c, 0x42, 0x09, 0x0a, + 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x48, 0x00, 0x52, 0x0f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x48, 0x00, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, + 0x03, 0x68, 0x75, 0x62, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x73, 0x61, + 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x75, 0x62, + 0x48, 0x00, 0x52, 0x03, 0x68, 0x75, 0x62, 0x12, 0x66, 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x70, 0x75, + 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6f, 0x73, 0x61, + 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, + 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x17, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, + 0x4d, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f, 0x73, 0x61, 0x63, + 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, + 0x75, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x63, + 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x44, + 0x0a, 0x0d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x12, 0x31, 0x0a, 0x06, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x48, 0x00, 0x52, + 0x06, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x12, 0x4a, 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, + 0x61, 0x6c, 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x48, 0x00, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x12, 0x47, 0x0a, 0x0e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6f, 0x73, + 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, + 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x0d, 0x73, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2e, 0x0a, 0x05, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6f, 0x73, + 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x65, + 0x61, 0x73, 0x65, 0x48, 0x00, 0x52, 0x05, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0e, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x18, 0x10, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x50, 0x50, + 0x6f, 0x6f, 0x6c, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x70, 0x50, + 0x6f, 0x6f, 0x6c, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x69, 0x70, + 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x73, 0x61, 0x63, 0x2e, 0x70, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, + 0x50, 0x48, 0x00, 0x52, 0x08, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x70, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2a, 0xa4, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, @@ -879,6 +929,7 @@ var file_osac_private_v1_event_type_proto_goTypes = []any{ (*SecurityGroup)(nil), // 11: osac.private.v1.SecurityGroup (*Lease)(nil), // 12: osac.private.v1.Lease (*PublicIPPool)(nil), // 13: osac.private.v1.PublicIPPool + (*PublicIP)(nil), // 14: osac.private.v1.PublicIP } var file_osac_private_v1_event_type_proto_depIdxs = []int32{ 0, // 0: osac.private.v1.Event.type:type_name -> osac.private.v1.EventType @@ -894,11 +945,12 @@ var file_osac_private_v1_event_type_proto_depIdxs = []int32{ 11, // 10: osac.private.v1.Event.security_group:type_name -> osac.private.v1.SecurityGroup 12, // 11: osac.private.v1.Event.lease:type_name -> osac.private.v1.Lease 13, // 12: osac.private.v1.Event.public_ip_pool:type_name -> osac.private.v1.PublicIPPool - 13, // [13:13] is the sub-list for method output_type - 13, // [13:13] is the sub-list for method input_type - 13, // [13:13] is the sub-list for extension type_name - 13, // [13:13] is the sub-list for extension extendee - 0, // [0:13] is the sub-list for field type_name + 14, // 13: osac.private.v1.Event.public_ip:type_name -> osac.private.v1.PublicIP + 14, // [14:14] is the sub-list for method output_type + 14, // [14:14] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name } func init() { file_osac_private_v1_event_type_proto_init() } @@ -915,6 +967,7 @@ func file_osac_private_v1_event_type_proto_init() { file_osac_private_v1_lease_type_proto_init() file_osac_private_v1_network_class_type_proto_init() file_osac_private_v1_public_ip_pool_type_proto_init() + file_osac_private_v1_public_ip_type_proto_init() file_osac_private_v1_security_group_type_proto_init() file_osac_private_v1_subnet_type_proto_init() file_osac_private_v1_virtual_network_type_proto_init() @@ -931,6 +984,7 @@ func file_osac_private_v1_event_type_proto_init() { (*event_SecurityGroup)(nil), (*event_Lease)(nil), (*event_PublicIpPool)(nil), + (*event_PublicIp)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/internal/cmd/service/start/grpcserver/start_grpc_server_cmd.go b/internal/cmd/service/start/grpcserver/start_grpc_server_cmd.go index 66e80dd42..8b2ffda8f 100644 --- a/internal/cmd/service/start/grpcserver/start_grpc_server_cmd.go +++ b/internal/cmd/service/start/grpcserver/start_grpc_server_cmd.go @@ -689,6 +689,34 @@ func (c *runnerContext) run(cmd *cobra.Command, argv []string) error { } privatev1.RegisterLeasesServer(grpcServer, privateLeasesServer) + // Create the public IPs server: + c.logger.InfoContext(ctx, "Creating public IPs server") + publicIPsServer, err := servers.NewPublicIPsServer(). + SetLogger(c.logger). + SetNotifier(notifier). + SetAttributionLogic(publicAttributionLogic). + SetTenancyLogic(publicTenancyLogic). + SetMetricsRegisterer(metricsRegisterer). + Build() + if err != nil { + return fmt.Errorf("failed to create public IPs server: %w", err) + } + publicv1.RegisterPublicIPsServer(grpcServer, publicIPsServer) + + // Create the private public IPs server: + c.logger.InfoContext(ctx, "Creating private public IPs server") + privatePublicIPsServer, err := servers.NewPrivatePublicIPsServer(). + SetLogger(c.logger). + SetNotifier(notifier). + SetAttributionLogic(privateAttributionLogic). + SetTenancyLogic(privateTenancyLogic). + SetMetricsRegisterer(metricsRegisterer). + Build() + if err != nil { + return fmt.Errorf("failed to create private public IPs server: %w", err) + } + privatev1.RegisterPublicIPsServer(grpcServer, privatePublicIPsServer) + // Create the console manager and server: c.logger.InfoContext(ctx, "Creating console server") hubConfigProvider := console.HubConfigProviderFromKubeconfigs( diff --git a/internal/cmd/service/start/restgateway/start_rest_gateway_cmd.go b/internal/cmd/service/start/restgateway/start_rest_gateway_cmd.go index 1813d4c2a..d6d9e9d8b 100644 --- a/internal/cmd/service/start/restgateway/start_rest_gateway_cmd.go +++ b/internal/cmd/service/start/restgateway/start_rest_gateway_cmd.go @@ -189,6 +189,10 @@ func (c *runnerContext) run(cmd *cobra.Command, argv []string) error { if err != nil { return err } + err = publicv1.RegisterPublicIPsHandler(ctx, gatewayMux, c.grpcClient) + if err != nil { + return err + } // Register the private API service handlers: err = privatev1.RegisterCapabilitiesHandler(ctx, gatewayMux, c.grpcClient) @@ -239,6 +243,10 @@ func (c *runnerContext) run(cmd *cobra.Command, argv []string) error { if err != nil { return err } + err = privatev1.RegisterPublicIPsHandler(ctx, gatewayMux, c.grpcClient) + if err != nil { + return err + } // Add the health endpoint: c.logger.InfoContext(ctx, "Adding health endpoint") diff --git a/internal/servers/generic_server.go b/internal/servers/generic_server.go index 4ea11291b..2bd441dcc 100644 --- a/internal/servers/generic_server.go +++ b/internal/servers/generic_server.go @@ -838,6 +838,8 @@ func (s *GenericServer[O]) setPayload(event *privatev1.Event, object proto.Messa event.SetSecurityGroup(object) case *privatev1.Lease: event.SetLease(object) + case *privatev1.PublicIP: + event.SetPublicIp(object) default: return fmt.Errorf("unknown object type '%T'", object) } diff --git a/internal/servers/private_public_ips_server.go b/internal/servers/private_public_ips_server.go new file mode 100644 index 000000000..c33cbd2c6 --- /dev/null +++ b/internal/servers/private_public_ips_server.go @@ -0,0 +1,182 @@ +/* +Copyright (c) 2026 Red Hat Inc. + +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 servers + +import ( + "context" + "errors" + "log/slog" + + "github.com/prometheus/client_golang/prometheus" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" + + privatev1 "github.com/osac-project/fulfillment-service/internal/api/osac/private/v1" + "github.com/osac-project/fulfillment-service/internal/auth" + "github.com/osac-project/fulfillment-service/internal/database" +) + +// PrivatePublicIPsServerBuilder contains the data and logic needed to create a PrivatePublicIPsServer. +type PrivatePublicIPsServerBuilder struct { + logger *slog.Logger + notifier *database.Notifier + attributionLogic auth.AttributionLogic + tenancyLogic auth.TenancyLogic + metricsRegisterer prometheus.Registerer +} + +var _ privatev1.PublicIPsServer = (*PrivatePublicIPsServer)(nil) + +// PrivatePublicIPsServer implements the private PublicIPs gRPC service. It delegates most operations to a +// GenericServer and adds pool-required validation on Create. +type PrivatePublicIPsServer struct { + privatev1.UnimplementedPublicIPsServer + + logger *slog.Logger + generic *GenericServer[*privatev1.PublicIP] +} + +// NewPrivatePublicIPsServer creates a builder that can then be used to configure and create a PrivatePublicIPsServer. +func NewPrivatePublicIPsServer() *PrivatePublicIPsServerBuilder { + return &PrivatePublicIPsServerBuilder{} +} + +// SetLogger sets the logger. This is mandatory. +func (b *PrivatePublicIPsServerBuilder) SetLogger(value *slog.Logger) *PrivatePublicIPsServerBuilder { + b.logger = value + return b +} + +// SetNotifier sets the notifier that will be used to send change notifications. +func (b *PrivatePublicIPsServerBuilder) SetNotifier(value *database.Notifier) *PrivatePublicIPsServerBuilder { + b.notifier = value + return b +} + +// SetAttributionLogic sets the logic that will be used to determine the creators for objects. This is mandatory. +func (b *PrivatePublicIPsServerBuilder) SetAttributionLogic(value auth.AttributionLogic) *PrivatePublicIPsServerBuilder { + b.attributionLogic = value + return b +} + +// SetTenancyLogic sets the tenancy logic that will be used to determine the tenants for objects. +func (b *PrivatePublicIPsServerBuilder) SetTenancyLogic(value auth.TenancyLogic) *PrivatePublicIPsServerBuilder { + b.tenancyLogic = value + return b +} + +// SetMetricsRegisterer sets the Prometheus registerer used to register the metrics for the underlying database +// access objects. This is optional. If not set, no metrics will be recorded. +func (b *PrivatePublicIPsServerBuilder) SetMetricsRegisterer(value prometheus.Registerer) *PrivatePublicIPsServerBuilder { + b.metricsRegisterer = value + return b +} + +// Build uses the configuration stored in the builder to create a new PrivatePublicIPsServer. +func (b *PrivatePublicIPsServerBuilder) Build() (result *PrivatePublicIPsServer, err error) { + // Check parameters: + if b.logger == nil { + err = errors.New("logger is mandatory") + return + } + if b.tenancyLogic == nil { + err = errors.New("tenancy logic is mandatory") + return + } + if b.attributionLogic == nil { + err = errors.New("attribution logic is mandatory") + return + } + + // Create the generic server: + generic, err := NewGenericServer[*privatev1.PublicIP](). + SetLogger(b.logger). + SetService(privatev1.PublicIPs_ServiceDesc.ServiceName). + SetNotifier(b.notifier). + SetAttributionLogic(b.attributionLogic). + SetTenancyLogic(b.tenancyLogic). + SetMetricsRegisterer(b.metricsRegisterer). + Build() + if err != nil { + return + } + + // Create and populate the object: + result = &PrivatePublicIPsServer{ + logger: b.logger, + generic: generic, + } + return +} + +func (s *PrivatePublicIPsServer) List(ctx context.Context, + request *privatev1.PublicIPsListRequest) (response *privatev1.PublicIPsListResponse, err error) { + err = s.generic.List(ctx, request, &response) + return +} + +func (s *PrivatePublicIPsServer) Get(ctx context.Context, + request *privatev1.PublicIPsGetRequest) (response *privatev1.PublicIPsGetResponse, err error) { + err = s.generic.Get(ctx, request, &response) + return +} + +func (s *PrivatePublicIPsServer) Create(ctx context.Context, + request *privatev1.PublicIPsCreateRequest) (response *privatev1.PublicIPsCreateResponse, err error) { + publicIP := request.GetObject() + + // Validate before creating: + err = s.validatePublicIP(ctx, publicIP) + if err != nil { + return + } + + err = s.generic.Create(ctx, request, &response) + return +} + +func (s *PrivatePublicIPsServer) Update(ctx context.Context, + request *privatev1.PublicIPsUpdateRequest) (response *privatev1.PublicIPsUpdateResponse, err error) { + err = s.generic.Update(ctx, request, &response) + return +} + +func (s *PrivatePublicIPsServer) Delete(ctx context.Context, + request *privatev1.PublicIPsDeleteRequest) (response *privatev1.PublicIPsDeleteResponse, err error) { + err = s.generic.Delete(ctx, request, &response) + return +} + +func (s *PrivatePublicIPsServer) Signal(ctx context.Context, + request *privatev1.PublicIPsSignalRequest) (response *privatev1.PublicIPsSignalResponse, err error) { + err = s.generic.Signal(ctx, request, &response) + return +} + +// validatePublicIP validates the PublicIP object before creation. +func (s *PrivatePublicIPsServer) validatePublicIP(ctx context.Context, + publicIP *privatev1.PublicIP) error { + if publicIP == nil { + return grpcstatus.Errorf(grpccodes.InvalidArgument, "public IP is mandatory") + } + spec := publicIP.GetSpec() + if spec == nil { + return grpcstatus.Errorf(grpccodes.InvalidArgument, "public IP spec is mandatory") + } + if spec.GetPool() == "" { + return grpcstatus.Errorf(grpccodes.InvalidArgument, + "field 'spec.pool' is required") + } + return nil +} diff --git a/internal/servers/private_public_ips_server_test.go b/internal/servers/private_public_ips_server_test.go new file mode 100644 index 000000000..78ff7b70c --- /dev/null +++ b/internal/servers/private_public_ips_server_test.go @@ -0,0 +1,320 @@ +/* +Copyright (c) 2026 Red Hat Inc. + +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 servers + +import ( + "context" + "fmt" + + "github.com/jackc/pgx/v5/pgxpool" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" + + privatev1 "github.com/osac-project/fulfillment-service/internal/api/osac/private/v1" + "github.com/osac-project/fulfillment-service/internal/database" + "github.com/osac-project/fulfillment-service/internal/database/dao" +) + +var _ = Describe("Private public IPs server", func() { + var ( + ctx context.Context + ) + + BeforeEach(func() { + var err error + + // Create a context: + ctx = context.Background() + + // Prepare the database pool: + db := server.MakeDatabase() + DeferCleanup(db.Close) + pool, err := pgxpool.New(ctx, db.MakeURL()) + Expect(err).ToNot(HaveOccurred()) + DeferCleanup(pool.Close) + + // Create the transaction manager: + tm, err := database.NewTxManager(). + SetLogger(logger). + SetPool(pool). + Build() + Expect(err).ToNot(HaveOccurred()) + + // Start a transaction and add it to the context: + tx, err := tm.Begin(ctx) + Expect(err).ToNot(HaveOccurred()) + DeferCleanup(func() { + err := tm.End(ctx, tx) + Expect(err).ToNot(HaveOccurred()) + }) + ctx = database.TxIntoContext(ctx, tx) + + // Create the tables: + err = dao.CreateTables[*privatev1.PublicIP](ctx) + Expect(err).ToNot(HaveOccurred()) + }) + + Describe("Creation", func() { + It("Can be built if all the required parameters are set", func() { + server, err := NewPrivatePublicIPsServer(). + SetLogger(logger). + SetAttributionLogic(attribution). + SetTenancyLogic(tenancy). + Build() + Expect(err).ToNot(HaveOccurred()) + Expect(server).ToNot(BeNil()) + }) + + It("Fails if logger is not set", func() { + server, err := NewPrivatePublicIPsServer(). + SetAttributionLogic(attribution). + SetTenancyLogic(tenancy). + Build() + Expect(err).To(MatchError("logger is mandatory")) + Expect(server).To(BeNil()) + }) + + It("Fails if tenancy logic is not set", func() { + server, err := NewPrivatePublicIPsServer(). + SetLogger(logger). + SetAttributionLogic(attribution). + Build() + Expect(err).To(MatchError("tenancy logic is mandatory")) + Expect(server).To(BeNil()) + }) + + It("Fails if attribution logic is not set", func() { + server, err := NewPrivatePublicIPsServer(). + SetLogger(logger). + SetTenancyLogic(tenancy). + Build() + Expect(err).To(MatchError("attribution logic is mandatory")) + Expect(server).To(BeNil()) + }) + }) + + Describe("Validation tests", func() { + var publicIPsServer *PrivatePublicIPsServer + + BeforeEach(func() { + var err error + + // Create the server: + publicIPsServer, err = NewPrivatePublicIPsServer(). + SetLogger(logger). + SetAttributionLogic(attribution). + SetTenancyLogic(tenancy). + Build() + Expect(err).ToNot(HaveOccurred()) + }) + + Context("Pool required validation", func() { + It("rejects nil object on Create", func() { + _, err := publicIPsServer.Create(ctx, privatev1.PublicIPsCreateRequest_builder{}.Build()) + Expect(err).To(HaveOccurred()) + status, ok := grpcstatus.FromError(err) + Expect(ok).To(BeTrue()) + Expect(status.Code()).To(Equal(grpccodes.InvalidArgument)) + Expect(err.Error()).To(ContainSubstring("public IP is mandatory")) + }) + + It("rejects nil spec on Create", func() { + _, err := publicIPsServer.Create(ctx, privatev1.PublicIPsCreateRequest_builder{ + Object: privatev1.PublicIP_builder{ + Metadata: privatev1.Metadata_builder{ + Tenants: []string{"shared"}, + }.Build(), + }.Build(), + }.Build()) + Expect(err).To(HaveOccurred()) + status, ok := grpcstatus.FromError(err) + Expect(ok).To(BeTrue()) + Expect(status.Code()).To(Equal(grpccodes.InvalidArgument)) + Expect(err.Error()).To(ContainSubstring("public IP spec is mandatory")) + }) + + It("rejects empty pool on Create", func() { + _, err := publicIPsServer.Create(ctx, privatev1.PublicIPsCreateRequest_builder{ + Object: privatev1.PublicIP_builder{ + Metadata: privatev1.Metadata_builder{ + Tenants: []string{"shared"}, + }.Build(), + Spec: privatev1.PublicIPSpec_builder{}.Build(), + }.Build(), + }.Build()) + Expect(err).To(HaveOccurred()) + status, ok := grpcstatus.FromError(err) + Expect(ok).To(BeTrue()) + Expect(status.Code()).To(Equal(grpccodes.InvalidArgument)) + Expect(err.Error()).To(ContainSubstring("spec.pool")) + }) + + It("accepts valid pool on Create", func() { + response, err := publicIPsServer.Create(ctx, privatev1.PublicIPsCreateRequest_builder{ + Object: privatev1.PublicIP_builder{ + Metadata: privatev1.Metadata_builder{ + Tenants: []string{"shared"}, + }.Build(), + Spec: privatev1.PublicIPSpec_builder{ + Pool: "test-pool", + }.Build(), + }.Build(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + Expect(response).ToNot(BeNil()) + Expect(response.GetObject().GetId()).ToNot(BeEmpty()) + }) + }) + }) + + Describe("CRUD operations", func() { + var publicIPsServer *PrivatePublicIPsServer + + BeforeEach(func() { + var err error + + // Create the server: + publicIPsServer, err = NewPrivatePublicIPsServer(). + SetLogger(logger). + SetAttributionLogic(attribution). + SetTenancyLogic(tenancy). + Build() + Expect(err).ToNot(HaveOccurred()) + }) + + It("creates PublicIP and generates ID", func() { + response, err := publicIPsServer.Create(ctx, privatev1.PublicIPsCreateRequest_builder{ + Object: privatev1.PublicIP_builder{ + Metadata: privatev1.Metadata_builder{ + Tenants: []string{"shared"}, + }.Build(), + Spec: privatev1.PublicIPSpec_builder{ + Pool: "my-pool", + }.Build(), + }.Build(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + Expect(response).ToNot(BeNil()) + object := response.GetObject() + Expect(object.GetId()).ToNot(BeEmpty()) + Expect(object.GetMetadata()).ToNot(BeNil()) + Expect(object.GetMetadata().GetCreationTimestamp()).ToNot(BeNil()) + }) + + It("retrieves PublicIP by ID", func() { + createResponse, err := publicIPsServer.Create(ctx, privatev1.PublicIPsCreateRequest_builder{ + Object: privatev1.PublicIP_builder{ + Metadata: privatev1.Metadata_builder{ + Tenants: []string{"shared"}, + }.Build(), + Spec: privatev1.PublicIPSpec_builder{ + Pool: "my-pool", + }.Build(), + }.Build(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + created := createResponse.GetObject() + + getResponse, err := publicIPsServer.Get(ctx, privatev1.PublicIPsGetRequest_builder{ + Id: created.GetId(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + retrieved := getResponse.GetObject() + Expect(proto.Equal(created, retrieved)).To(BeTrue()) + }) + + It("lists PublicIPs", func() { + const count = 3 + for i := range count { + _, err := publicIPsServer.Create(ctx, privatev1.PublicIPsCreateRequest_builder{ + Object: privatev1.PublicIP_builder{ + Metadata: privatev1.Metadata_builder{ + Tenants: []string{"shared"}, + }.Build(), + Spec: privatev1.PublicIPSpec_builder{ + Pool: fmt.Sprintf("pool-%d", i), + }.Build(), + }.Build(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + } + + response, err := publicIPsServer.List(ctx, privatev1.PublicIPsListRequest_builder{}.Build()) + Expect(err).ToNot(HaveOccurred()) + Expect(response.GetItems()).To(HaveLen(count)) + }) + + It("updates PublicIP", func() { + createResponse, err := publicIPsServer.Create(ctx, privatev1.PublicIPsCreateRequest_builder{ + Object: privatev1.PublicIP_builder{ + Metadata: privatev1.Metadata_builder{ + Name: "original-name", + Tenants: []string{"shared"}, + }.Build(), + Spec: privatev1.PublicIPSpec_builder{ + Pool: "my-pool", + }.Build(), + }.Build(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + object := createResponse.GetObject() + + // Update the name: + object.GetMetadata().Name = "updated-name" + updateResponse, err := publicIPsServer.Update(ctx, privatev1.PublicIPsUpdateRequest_builder{ + Object: object, + }.Build()) + Expect(err).ToNot(HaveOccurred()) + + // Verify via Get: + getResponse, err := publicIPsServer.Get(ctx, privatev1.PublicIPsGetRequest_builder{ + Id: updateResponse.GetObject().GetId(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + Expect(getResponse.GetObject().GetMetadata().GetName()).To(Equal("updated-name")) + }) + + It("soft deletes PublicIP", func() { + createResponse, err := publicIPsServer.Create(ctx, privatev1.PublicIPsCreateRequest_builder{ + Object: privatev1.PublicIP_builder{ + Metadata: privatev1.Metadata_builder{ + Finalizers: []string{"test-finalizer"}, + Tenants: []string{"shared"}, + }.Build(), + Spec: privatev1.PublicIPSpec_builder{ + Pool: "my-pool", + }.Build(), + }.Build(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + object := createResponse.GetObject() + + // Delete: + _, err = publicIPsServer.Delete(ctx, privatev1.PublicIPsDeleteRequest_builder{ + Id: object.GetId(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + + // Verify soft delete (deletion_timestamp set, object still retrievable): + getResponse, err := publicIPsServer.Get(ctx, privatev1.PublicIPsGetRequest_builder{ + Id: object.GetId(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + Expect(getResponse.GetObject().GetMetadata().GetDeletionTimestamp()).ToNot(BeNil()) + }) + }) +}) diff --git a/internal/servers/public_ips_server.go b/internal/servers/public_ips_server.go new file mode 100644 index 000000000..fc39ae1ab --- /dev/null +++ b/internal/servers/public_ips_server.go @@ -0,0 +1,272 @@ +/* +Copyright (c) 2026 Red Hat Inc. + +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 servers + +import ( + "context" + "errors" + "log/slog" + + "github.com/prometheus/client_golang/prometheus" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" + + privatev1 "github.com/osac-project/fulfillment-service/internal/api/osac/private/v1" + publicv1 "github.com/osac-project/fulfillment-service/internal/api/osac/public/v1" + "github.com/osac-project/fulfillment-service/internal/auth" + "github.com/osac-project/fulfillment-service/internal/database" +) + +type PublicIPsServerBuilder struct { + logger *slog.Logger + notifier *database.Notifier + attributionLogic auth.AttributionLogic + tenancyLogic auth.TenancyLogic + metricsRegisterer prometheus.Registerer +} + +var _ publicv1.PublicIPsServer = (*PublicIPsServer)(nil) + +type PublicIPsServer struct { + publicv1.UnimplementedPublicIPsServer + + logger *slog.Logger + delegate privatev1.PublicIPsServer + inMapper *GenericMapper[*publicv1.PublicIP, *privatev1.PublicIP] + outMapper *GenericMapper[*privatev1.PublicIP, *publicv1.PublicIP] +} + +func NewPublicIPsServer() *PublicIPsServerBuilder { + return &PublicIPsServerBuilder{} +} + +// SetLogger sets the logger to use. This is mandatory. +func (b *PublicIPsServerBuilder) SetLogger(value *slog.Logger) *PublicIPsServerBuilder { + b.logger = value + return b +} + +// SetNotifier sets the notifier to use. This is optional. +func (b *PublicIPsServerBuilder) SetNotifier(value *database.Notifier) *PublicIPsServerBuilder { + b.notifier = value + return b +} + +// SetAttributionLogic sets the attribution logic to use. This is mandatory. +func (b *PublicIPsServerBuilder) SetAttributionLogic(value auth.AttributionLogic) *PublicIPsServerBuilder { + b.attributionLogic = value + return b +} + +// SetTenancyLogic sets the tenancy logic to use. This is mandatory. +func (b *PublicIPsServerBuilder) SetTenancyLogic(value auth.TenancyLogic) *PublicIPsServerBuilder { + b.tenancyLogic = value + return b +} + +// SetMetricsRegisterer sets the Prometheus registerer used to register the metrics for the underlying database +// access objects. This is optional. If not set, no metrics will be recorded. +func (b *PublicIPsServerBuilder) SetMetricsRegisterer(value prometheus.Registerer) *PublicIPsServerBuilder { + b.metricsRegisterer = value + return b +} + +func (b *PublicIPsServerBuilder) Build() (result *PublicIPsServer, err error) { + // Check parameters: + if b.logger == nil { + err = errors.New("logger is mandatory") + return + } + if b.tenancyLogic == nil { + err = errors.New("tenancy logic is mandatory") + return + } + if b.attributionLogic == nil { + err = errors.New("attribution logic is mandatory") + return + } + + // Create the mappers: + inMapper, err := NewGenericMapper[*publicv1.PublicIP, *privatev1.PublicIP](). + SetLogger(b.logger). + SetStrict(true). + Build() + if err != nil { + return + } + outMapper, err := NewGenericMapper[*privatev1.PublicIP, *publicv1.PublicIP](). + SetLogger(b.logger). + SetStrict(false). + Build() + if err != nil { + return + } + + // Create the private server to delegate to: + delegate, err := NewPrivatePublicIPsServer(). + SetLogger(b.logger). + SetNotifier(b.notifier). + SetAttributionLogic(b.attributionLogic). + SetTenancyLogic(b.tenancyLogic). + SetMetricsRegisterer(b.metricsRegisterer). + Build() + if err != nil { + return + } + + // Create and populate the object: + result = &PublicIPsServer{ + logger: b.logger, + delegate: delegate, + inMapper: inMapper, + outMapper: outMapper, + } + return +} + +func (s *PublicIPsServer) List(ctx context.Context, + request *publicv1.PublicIPsListRequest) (response *publicv1.PublicIPsListResponse, err error) { + // Create private request with same parameters: + privateRequest := &privatev1.PublicIPsListRequest{} + privateRequest.SetOffset(request.GetOffset()) + privateRequest.SetLimit(request.GetLimit()) + privateRequest.SetFilter(request.GetFilter()) + privateRequest.SetOrder(request.GetOrder()) + + // Delegate to private server: + privateResponse, err := s.delegate.List(ctx, privateRequest) + if err != nil { + return nil, err + } + + // Map private response to public format: + privateItems := privateResponse.GetItems() + publicItems := make([]*publicv1.PublicIP, len(privateItems)) + for i, privateItem := range privateItems { + publicItem := &publicv1.PublicIP{} + err = s.outMapper.Copy(ctx, privateItem, publicItem) + if err != nil { + s.logger.ErrorContext( + ctx, + "Failed to map private public IP to public", + slog.Any("error", err), + ) + return nil, grpcstatus.Errorf(grpccodes.Internal, "failed to process public IPs") + } + publicItems[i] = publicItem + } + + // Create the public response: + response = &publicv1.PublicIPsListResponse{} + response.SetSize(privateResponse.GetSize()) + response.SetTotal(privateResponse.GetTotal()) + response.SetItems(publicItems) + return +} + +func (s *PublicIPsServer) Get(ctx context.Context, + request *publicv1.PublicIPsGetRequest) (response *publicv1.PublicIPsGetResponse, err error) { + // Create private request: + privateRequest := &privatev1.PublicIPsGetRequest{} + privateRequest.SetId(request.GetId()) + + // Delegate to private server: + privateResponse, err := s.delegate.Get(ctx, privateRequest) + if err != nil { + return nil, err + } + + // Map private response to public format: + privatePublicIP := privateResponse.GetObject() + publicPublicIP := &publicv1.PublicIP{} + err = s.outMapper.Copy(ctx, privatePublicIP, publicPublicIP) + if err != nil { + s.logger.ErrorContext( + ctx, + "Failed to map private public IP to public", + slog.Any("error", err), + ) + return nil, grpcstatus.Errorf(grpccodes.Internal, "failed to process public IP") + } + + // Create the public response: + response = &publicv1.PublicIPsGetResponse{} + response.SetObject(publicPublicIP) + return +} + +func (s *PublicIPsServer) Create(ctx context.Context, + request *publicv1.PublicIPsCreateRequest) (response *publicv1.PublicIPsCreateResponse, err error) { + // Map the public IP to private format: + publicPublicIP := request.GetObject() + if publicPublicIP == nil { + err = grpcstatus.Errorf(grpccodes.InvalidArgument, "object is mandatory") + return + } + privatePublicIP := &privatev1.PublicIP{} + err = s.inMapper.Copy(ctx, publicPublicIP, privatePublicIP) + if err != nil { + s.logger.ErrorContext( + ctx, + "Failed to map public IP to private", + slog.Any("error", err), + ) + err = grpcstatus.Errorf(grpccodes.Internal, "failed to process public IP") + return + } + + // Delegate to the private server: + privateRequest := &privatev1.PublicIPsCreateRequest{} + privateRequest.SetObject(privatePublicIP) + privateResponse, err := s.delegate.Create(ctx, privateRequest) + if err != nil { + return nil, err + } + + // Map the private response back to public format: + createdPrivatePublicIP := privateResponse.GetObject() + createdPublicPublicIP := &publicv1.PublicIP{} + err = s.outMapper.Copy(ctx, createdPrivatePublicIP, createdPublicPublicIP) + if err != nil { + s.logger.ErrorContext( + ctx, + "Failed to map private public IP to public", + slog.Any("error", err), + ) + err = grpcstatus.Errorf(grpccodes.Internal, "failed to process public IP") + return + } + + // Create the public response: + response = &publicv1.PublicIPsCreateResponse{} + response.SetObject(createdPublicPublicIP) + return +} + +func (s *PublicIPsServer) Delete(ctx context.Context, + request *publicv1.PublicIPsDeleteRequest) (response *publicv1.PublicIPsDeleteResponse, err error) { + // Create private request: + privateRequest := &privatev1.PublicIPsDeleteRequest{} + privateRequest.SetId(request.GetId()) + + // Delegate to private server: + _, err = s.delegate.Delete(ctx, privateRequest) + if err != nil { + return nil, err + } + + // Create the public response: + response = &publicv1.PublicIPsDeleteResponse{} + return +} diff --git a/internal/servers/public_ips_server_test.go b/internal/servers/public_ips_server_test.go new file mode 100644 index 000000000..dabd4c512 --- /dev/null +++ b/internal/servers/public_ips_server_test.go @@ -0,0 +1,289 @@ +/* +Copyright (c) 2026 Red Hat Inc. + +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 servers + +import ( + "context" + "fmt" + + "github.com/jackc/pgx/v5/pgxpool" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "google.golang.org/protobuf/proto" + + privatev1 "github.com/osac-project/fulfillment-service/internal/api/osac/private/v1" + publicv1 "github.com/osac-project/fulfillment-service/internal/api/osac/public/v1" + "github.com/osac-project/fulfillment-service/internal/database" + "github.com/osac-project/fulfillment-service/internal/database/dao" +) + +var _ = Describe("Public IPs server", func() { + var ( + ctx context.Context + tx database.Tx + ) + + BeforeEach(func() { + var err error + + // Create a context: + ctx = context.Background() + + // Prepare the database pool: + db := server.MakeDatabase() + DeferCleanup(db.Close) + pool, err := pgxpool.New(ctx, db.MakeURL()) + Expect(err).ToNot(HaveOccurred()) + DeferCleanup(pool.Close) + + // Create the transaction manager: + tm, err := database.NewTxManager(). + SetLogger(logger). + SetPool(pool). + Build() + Expect(err).ToNot(HaveOccurred()) + + // Start a transaction and add it to the context: + tx, err = tm.Begin(ctx) + Expect(err).ToNot(HaveOccurred()) + DeferCleanup(func() { + err := tm.End(ctx, tx) + Expect(err).ToNot(HaveOccurred()) + }) + ctx = database.TxIntoContext(ctx, tx) + + // Create the tables: + err = dao.CreateTables[*privatev1.PublicIP](ctx) + Expect(err).ToNot(HaveOccurred()) + }) + + Describe("Creation", func() { + It("Can be built if all the required parameters are set", func() { + server, err := NewPublicIPsServer(). + SetLogger(logger). + SetAttributionLogic(attribution). + SetTenancyLogic(tenancy). + Build() + Expect(err).ToNot(HaveOccurred()) + Expect(server).ToNot(BeNil()) + }) + + It("Fails if logger is not set", func() { + server, err := NewPublicIPsServer(). + SetAttributionLogic(attribution). + SetTenancyLogic(tenancy). + Build() + Expect(err).To(MatchError("logger is mandatory")) + Expect(server).To(BeNil()) + }) + + It("Fails if tenancy logic is not set", func() { + server, err := NewPublicIPsServer(). + SetLogger(logger). + SetAttributionLogic(attribution). + Build() + Expect(err).To(MatchError("tenancy logic is mandatory")) + Expect(server).To(BeNil()) + }) + + It("Fails if attribution logic is not set", func() { + server, err := NewPublicIPsServer(). + SetLogger(logger). + SetTenancyLogic(tenancy). + Build() + Expect(err).To(MatchError("attribution logic is mandatory")) + Expect(server).To(BeNil()) + }) + }) + + Describe("Behaviour", func() { + var publicIPsServer *PublicIPsServer + + BeforeEach(func() { + var err error + + // Create the server: + publicIPsServer, err = NewPublicIPsServer(). + SetLogger(logger). + SetAttributionLogic(attribution). + SetTenancyLogic(tenancy). + Build() + Expect(err).ToNot(HaveOccurred()) + }) + + It("Creates object", func() { + response, err := publicIPsServer.Create(ctx, publicv1.PublicIPsCreateRequest_builder{ + Object: publicv1.PublicIP_builder{ + Spec: publicv1.PublicIPSpec_builder{ + Pool: "my-pool", + }.Build(), + }.Build(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + Expect(response).ToNot(BeNil()) + object := response.GetObject() + Expect(object).ToNot(BeNil()) + Expect(object.GetId()).ToNot(BeEmpty()) + }) + + It("List objects", func() { + // Create a few objects: + const count = 10 + for i := range count { + _, err := publicIPsServer.Create(ctx, publicv1.PublicIPsCreateRequest_builder{ + Object: publicv1.PublicIP_builder{ + Spec: publicv1.PublicIPSpec_builder{ + Pool: fmt.Sprintf("pool-%d", i), + }.Build(), + }.Build(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + } + + // List the objects: + response, err := publicIPsServer.List(ctx, publicv1.PublicIPsListRequest_builder{}.Build()) + Expect(err).ToNot(HaveOccurred()) + Expect(response).ToNot(BeNil()) + items := response.GetItems() + Expect(items).To(HaveLen(count)) + }) + + It("List objects with limit", func() { + // Create a few objects: + const count = 10 + for i := range count { + _, err := publicIPsServer.Create(ctx, publicv1.PublicIPsCreateRequest_builder{ + Object: publicv1.PublicIP_builder{ + Spec: publicv1.PublicIPSpec_builder{ + Pool: fmt.Sprintf("pool-%d", i), + }.Build(), + }.Build(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + } + + // List the objects: + response, err := publicIPsServer.List(ctx, publicv1.PublicIPsListRequest_builder{ + Limit: proto.Int32(1), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + Expect(response.GetSize()).To(BeNumerically("==", 1)) + }) + + It("List objects with offset", func() { + // Create a few objects: + const count = 10 + for i := range count { + _, err := publicIPsServer.Create(ctx, publicv1.PublicIPsCreateRequest_builder{ + Object: publicv1.PublicIP_builder{ + Spec: publicv1.PublicIPSpec_builder{ + Pool: fmt.Sprintf("pool-%d", i), + }.Build(), + }.Build(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + } + + // List the objects: + response, err := publicIPsServer.List(ctx, publicv1.PublicIPsListRequest_builder{ + Offset: proto.Int32(1), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + Expect(response.GetSize()).To(BeNumerically("==", count-1)) + }) + + It("List objects with filter", func() { + // Create a few objects: + const count = 10 + var objects []*publicv1.PublicIP + for i := range count { + response, err := publicIPsServer.Create(ctx, publicv1.PublicIPsCreateRequest_builder{ + Object: publicv1.PublicIP_builder{ + Spec: publicv1.PublicIPSpec_builder{ + Pool: fmt.Sprintf("pool-%d", i), + }.Build(), + }.Build(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + objects = append(objects, response.GetObject()) + } + + // List the objects: + for _, object := range objects { + response, err := publicIPsServer.List(ctx, publicv1.PublicIPsListRequest_builder{ + Filter: proto.String(fmt.Sprintf("this.id == '%s'", object.GetId())), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + Expect(response.GetSize()).To(BeNumerically("==", 1)) + Expect(response.GetItems()[0].GetId()).To(Equal(object.GetId())) + } + }) + + It("Get object", func() { + // Create the object: + createResponse, err := publicIPsServer.Create(ctx, publicv1.PublicIPsCreateRequest_builder{ + Object: publicv1.PublicIP_builder{ + Spec: publicv1.PublicIPSpec_builder{ + Pool: "my-pool", + }.Build(), + }.Build(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + + // Get it: + getResponse, err := publicIPsServer.Get(ctx, publicv1.PublicIPsGetRequest_builder{ + Id: createResponse.GetObject().GetId(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + Expect(proto.Equal(createResponse.GetObject(), getResponse.GetObject())).To(BeTrue()) + }) + + It("Delete object", func() { + // Create the object: + createResponse, err := publicIPsServer.Create(ctx, publicv1.PublicIPsCreateRequest_builder{ + Object: publicv1.PublicIP_builder{ + Spec: publicv1.PublicIPSpec_builder{ + Pool: "my-pool", + }.Build(), + }.Build(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + object := createResponse.GetObject() + + // Add a finalizer, as otherwise the object will be immediately deleted and archived and it + // won't be possible to verify the deletion timestamp. This can't be done using the server + // because this is a public object, and public objects don't have the finalizers field. + _, err = tx.Exec( + ctx, + `update public_ips set finalizers = '{"a"}' where id = $1`, + object.GetId(), + ) + Expect(err).ToNot(HaveOccurred()) + + // Delete the object: + _, err = publicIPsServer.Delete(ctx, publicv1.PublicIPsDeleteRequest_builder{ + Id: object.GetId(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + + // Get and verify: + getResponse, err := publicIPsServer.Get(ctx, publicv1.PublicIPsGetRequest_builder{ + Id: object.GetId(), + }.Build()) + Expect(err).ToNot(HaveOccurred()) + object = getResponse.GetObject() + Expect(object.GetMetadata().GetDeletionTimestamp()).ToNot(BeNil()) + }) + }) +}) diff --git a/proto/private/osac/private/v1/event_type.proto b/proto/private/osac/private/v1/event_type.proto index fb19d6095..69996bcb8 100644 --- a/proto/private/osac/private/v1/event_type.proto +++ b/proto/private/osac/private/v1/event_type.proto @@ -24,6 +24,7 @@ import "osac/private/v1/hub_type.proto"; import "osac/private/v1/lease_type.proto"; import "osac/private/v1/network_class_type.proto"; import "osac/private/v1/public_ip_pool_type.proto"; +import "osac/private/v1/public_ip_type.proto"; import "osac/private/v1/security_group_type.proto"; import "osac/private/v1/subnet_type.proto"; import "osac/private/v1/virtual_network_type.proto"; @@ -50,6 +51,7 @@ message Event { SecurityGroup security_group = 14; Lease lease = 15; PublicIPPool public_ip_pool = 16; + PublicIP public_ip = 17; } }