From a40fe67709590228e14bc67c54f8e48068063e22 Mon Sep 17 00:00:00 2001 From: Leela Venkaiah G Date: Mon, 30 Oct 2023 11:38:00 +0530 Subject: [PATCH] store client information on storageconsumer status - adds new fields to existing RPC message - these fields are updated in status of corresponding storageconsumer CRs - the status will be helpful for exporting new metrics Signed-off-by: Leela Venkaiah G --- api/v1alpha1/storageconsumer_types.go | 10 ++ api/v1alpha1/zz_generated.deepcopy.go | 16 ++ .../ocs.openshift.io_storageconsumers.yaml | 13 ++ .../ocs.openshift.io_storageconsumers.yaml | 13 ++ .../manifests/storageconsumer.crd.yaml | 13 ++ services/provider/client/client.go | 14 +- services/provider/clientstatus/status.go | 9 ++ services/provider/pb/provider.pb.go | 139 ++++++++++-------- services/provider/pb/storageclient_status.go | 26 ++++ services/provider/proto/provider.proto | 2 + services/provider/server/consumer.go | 39 ++--- services/provider/server/consumer_test.go | 48 +++++- services/provider/server/server.go | 16 +- services/provider/server/server_test.go | 13 +- 14 files changed, 265 insertions(+), 106 deletions(-) create mode 100644 services/provider/clientstatus/status.go create mode 100644 services/provider/pb/storageclient_status.go diff --git a/api/v1alpha1/storageconsumer_types.go b/api/v1alpha1/storageconsumer_types.go index f0ae411b95..b76daa1315 100644 --- a/api/v1alpha1/storageconsumer_types.go +++ b/api/v1alpha1/storageconsumer_types.go @@ -62,6 +62,16 @@ type StorageConsumerStatus struct { CephResources []*CephResourcesSpec `json:"cephResources,omitempty"` // Timestamp of last heartbeat received from consumer LastHeartbeat metav1.Time `json:"lastHeartbeat,omitempty"` + // Information of storage client received from consumer + Client ClientStatus `json:"client,omitempty"` +} + +// ClientStatus is the information pushed from connected storage client +type ClientStatus struct { + // StorageClient Platform Version + PlatformVersion string `json:"platformVersion"` + // StorageClient Operator Version + OperatorVersion string `json:"operatorVersion"` } //+kubebuilder:object:root=true diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 7614dbbfe4..3dae5a8135 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -47,6 +47,21 @@ func (in *CephResourcesSpec) DeepCopy() *CephResourcesSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClientStatus) DeepCopyInto(out *ClientStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientStatus. +func (in *ClientStatus) DeepCopy() *ClientStatus { + if in == nil { + return nil + } + out := new(ClientStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *StorageClassRequest) DeepCopyInto(out *StorageClassRequest) { *out = *in @@ -236,6 +251,7 @@ func (in *StorageConsumerStatus) DeepCopyInto(out *StorageConsumerStatus) { } } in.LastHeartbeat.DeepCopyInto(&out.LastHeartbeat) + out.Client = in.Client } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageConsumerStatus. diff --git a/config/crd/bases/ocs.openshift.io_storageconsumers.yaml b/config/crd/bases/ocs.openshift.io_storageconsumers.yaml index b53da54942..fe6bc1d457 100644 --- a/config/crd/bases/ocs.openshift.io_storageconsumers.yaml +++ b/config/crd/bases/ocs.openshift.io_storageconsumers.yaml @@ -66,6 +66,19 @@ spec: type: string type: object type: array + client: + description: Information of storage client received from consumer + properties: + operatorVersion: + description: StorageClient Operator Version + type: string + platformVersion: + description: StorageClient Platform Version + type: string + required: + - operatorVersion + - platformVersion + type: object lastHeartbeat: description: Timestamp of last heartbeat received from consumer format: date-time diff --git a/deploy/csv-templates/crds/ocs/ocs.openshift.io_storageconsumers.yaml b/deploy/csv-templates/crds/ocs/ocs.openshift.io_storageconsumers.yaml index b53da54942..fe6bc1d457 100644 --- a/deploy/csv-templates/crds/ocs/ocs.openshift.io_storageconsumers.yaml +++ b/deploy/csv-templates/crds/ocs/ocs.openshift.io_storageconsumers.yaml @@ -66,6 +66,19 @@ spec: type: string type: object type: array + client: + description: Information of storage client received from consumer + properties: + operatorVersion: + description: StorageClient Operator Version + type: string + platformVersion: + description: StorageClient Platform Version + type: string + required: + - operatorVersion + - platformVersion + type: object lastHeartbeat: description: Timestamp of last heartbeat received from consumer format: date-time diff --git a/deploy/ocs-operator/manifests/storageconsumer.crd.yaml b/deploy/ocs-operator/manifests/storageconsumer.crd.yaml index d30f49b5d1..2950e94745 100644 --- a/deploy/ocs-operator/manifests/storageconsumer.crd.yaml +++ b/deploy/ocs-operator/manifests/storageconsumer.crd.yaml @@ -65,6 +65,19 @@ spec: type: string type: object type: array + client: + description: Information of storage client received from consumer + properties: + operatorVersion: + description: StorageClient Operator Version + type: string + platformVersion: + description: StorageClient Platform Version + type: string + required: + - operatorVersion + - platformVersion + type: object lastHeartbeat: description: Timestamp of last heartbeat received from consumer format: date-time diff --git a/services/provider/client/client.go b/services/provider/client/client.go index bbfd8db0bf..e11ce16602 100644 --- a/services/provider/client/client.go +++ b/services/provider/client/client.go @@ -6,6 +6,7 @@ import ( "fmt" "time" + cs "github.com/red-hat-storage/ocs-operator/v4/services/provider/clientstatus" pb "github.com/red-hat-storage/ocs-operator/v4/services/provider/pb" "google.golang.org/grpc" @@ -188,13 +189,18 @@ func (cc *OCSProviderClient) GetStorageClassClaimConfig(ctx context.Context, con return cc.Client.GetStorageClassClaimConfig(apiCtx, req) } -func (cc *OCSProviderClient) ReportStatus(ctx context.Context, consumerUUID string) (*pb.ReportStatusResponse, error) { +func NewStorageClientStatus() cs.StorageClientStatus { + return &pb.ReportStatusRequest{} +} + +func (cc *OCSProviderClient) ReportStatus(ctx context.Context, consumerUUID string, status cs.StorageClientStatus) (*pb.ReportStatusResponse, error) { if cc.Client == nil || cc.clientConn == nil { return nil, fmt.Errorf("Provider client is closed") } - req := &pb.ReportStatusRequest{ - StorageConsumerUUID: consumerUUID, - } + + // panic if the request wasn't constructed using "NewStorageClientStatus()" + req := status.(*pb.ReportStatusRequest) + req.StorageConsumerUUID = consumerUUID apiCtx, cancel := context.WithTimeout(ctx, cc.timeout) defer cancel() diff --git a/services/provider/clientstatus/status.go b/services/provider/clientstatus/status.go new file mode 100644 index 0000000000..1b2506891f --- /dev/null +++ b/services/provider/clientstatus/status.go @@ -0,0 +1,9 @@ +package clientstatus + +type StorageClientStatus interface { + GetPlatformVersion() string + GetOperatorVersion() string + + SetPlatformVersion(string) StorageClientStatus + SetOperatorVersion(string) StorageClientStatus +} diff --git a/services/provider/pb/provider.pb.go b/services/provider/pb/provider.pb.go index 4816a535fa..3f89cd85a6 100644 --- a/services/provider/pb/provider.pb.go +++ b/services/provider/pb/provider.pb.go @@ -852,7 +852,9 @@ type ReportStatusRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - StorageConsumerUUID string `protobuf:"bytes,1,opt,name=storageConsumerUUID,proto3" json:"storageConsumerUUID,omitempty"` + StorageConsumerUUID string `protobuf:"bytes,1,opt,name=storageConsumerUUID,proto3" json:"storageConsumerUUID,omitempty"` + ClientPlatformVersion string `protobuf:"bytes,2,opt,name=clientPlatformVersion,proto3" json:"clientPlatformVersion,omitempty"` + ClientOperatorVersion string `protobuf:"bytes,3,opt,name=clientOperatorVersion,proto3" json:"clientOperatorVersion,omitempty"` } func (x *ReportStatusRequest) Reset() { @@ -894,6 +896,20 @@ func (x *ReportStatusRequest) GetStorageConsumerUUID() string { return "" } +func (x *ReportStatusRequest) GetClientPlatformVersion() string { + if x != nil { + return x.ClientPlatformVersion + } + return "" +} + +func (x *ReportStatusRequest) GetClientOperatorVersion() string { + if x != nil { + return x.ClientOperatorVersion + } + return "" +} + type ReportStatusResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1031,65 +1047,72 @@ var file_provider_proto_rawDesc = []byte{ 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, - 0x47, 0x0a, 0x13, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x13, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x32, 0xb4, 0x06, 0x0a, 0x0b, 0x4f, 0x43, 0x53, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x12, 0x58, 0x0a, 0x0f, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6d, 0x65, 0x72, 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x4f, - 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x2e, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x10, 0x47, 0x65, - 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1e, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x5b, 0x0a, 0x10, 0x4f, 0x66, 0x66, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6d, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0xb3, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x13, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, + 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44, 0x12, 0x34, 0x0a, 0x15, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x34, 0x0a, 0x15, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xb4, 0x06, + 0x0a, 0x0b, 0x4f, 0x43, 0x53, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x58, 0x0a, + 0x0f, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, + 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x4f, 0x6e, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x4f, 0x6e, + 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1e, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, + 0x0a, 0x10, 0x4f, 0x66, 0x66, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, + 0x65, 0x72, 0x12, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x4f, 0x66, + 0x66, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x4f, 0x66, 0x66, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x2e, 0x4f, 0x66, 0x66, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6a, - 0x0a, 0x15, 0x41, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x4f, 0x6e, 0x62, - 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x2e, 0x41, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x4f, 0x6e, - 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x41, 0x63, 0x6b, 0x6e, 0x6f, - 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x18, 0x46, 0x75, - 0x6c, 0x66, 0x69, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, - 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x2e, 0x46, 0x75, 0x6c, 0x66, 0x69, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x75, 0x6c, - 0x66, 0x69, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, - 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x70, 0x0a, 0x17, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x28, 0x2e, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f, 0x72, - 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6a, 0x0a, 0x15, 0x41, + 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, + 0x64, 0x69, 0x6e, 0x67, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, + 0x41, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x41, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, + 0x64, 0x67, 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x18, 0x46, 0x75, 0x6c, 0x66, 0x69, + 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, + 0x61, 0x69, 0x6d, 0x12, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x46, + 0x75, 0x6c, 0x66, 0x69, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x75, 0x6c, 0x66, 0x69, 0x6c, + 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, + 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x70, 0x0a, 0x17, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, - 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x73, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, - 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, - 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0c, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, 0x2f, 0x3b, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x76, + 0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, + 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, + 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, + 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, + 0x61, 0x69, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0c, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, 0x2f, 0x3b, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/services/provider/pb/storageclient_status.go b/services/provider/pb/storageclient_status.go new file mode 100644 index 0000000000..f417fe4454 --- /dev/null +++ b/services/provider/pb/storageclient_status.go @@ -0,0 +1,26 @@ +package providerpb + +import ( + cs "github.com/red-hat-storage/ocs-operator/v4/services/provider/clientstatus" +) + +// ensure ReportStatusRequest satisfies StorageClientStatus interface +var _ cs.StorageClientStatus = &ReportStatusRequest{} + +func (r *ReportStatusRequest) GetPlatformVersion() string { + return r.ClientPlatformVersion +} + +func (r *ReportStatusRequest) GetOperatorVersion() string { + return r.ClientOperatorVersion +} + +func (r *ReportStatusRequest) SetPlatformVersion(version string) cs.StorageClientStatus { + r.ClientPlatformVersion = version + return r +} + +func (r *ReportStatusRequest) SetOperatorVersion(version string) cs.StorageClientStatus { + r.ClientOperatorVersion = version + return r +} diff --git a/services/provider/proto/provider.proto b/services/provider/proto/provider.proto index dc76790d5e..63200f36fd 100644 --- a/services/provider/proto/provider.proto +++ b/services/provider/proto/provider.proto @@ -155,6 +155,8 @@ message StorageClassClaimConfigResponse{ message ReportStatusRequest{ string storageConsumerUUID = 1; + string clientPlatformVersion = 2; + string clientOperatorVersion = 3; } message ReportStatusResponse{} diff --git a/services/provider/server/consumer.go b/services/provider/server/consumer.go index 0d6fca2b91..2690471d56 100644 --- a/services/provider/server/consumer.go +++ b/services/provider/server/consumer.go @@ -2,12 +2,12 @@ package server import ( "context" - "encoding/json" "errors" "fmt" "sync" ocsv1alpha1 "github.com/red-hat-storage/ocs-operator/v4/api/v1alpha1" + cs "github.com/red-hat-storage/ocs-operator/v4/services/provider/clientstatus" kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -199,36 +199,19 @@ func (c *ocsConsumerManager) Get(ctx context.Context, id string) (*ocsv1alpha1.S return consumerObj, nil } -func (c *ocsConsumerManager) UpdateStatusLastHeatbeat(ctx context.Context, id string) error { - uid := types.UID(id) - - c.mutex.RLock() - consumerName, ok := c.nameByUID[uid] - if !ok { - c.mutex.RUnlock() - klog.Warningf("no storageConsumer found with UID %q", id) - return nil +func (c *ocsConsumerManager) UpdateConsumerStatus(ctx context.Context, id string, status cs.StorageClientStatus) error { + consumerObj, err := c.Get(ctx, id) + if err != nil { + return err } - c.mutex.RUnlock() - patchInfo := struct { - Op string `json:"op"` - Path string `json:"path"` - Value interface{} `json:"value"` - }{ - Op: "replace", - Path: "/status/lastHeartbeat", - Value: metav1.Now(), - } - jsonPatchInfo, _ := json.Marshal([]interface{}{patchInfo}) - patch := client.RawPatch(types.JSONPatchType, jsonPatchInfo) + consumerObj.Status.LastHeartbeat = metav1.Now() + consumerObj.Status.Client.PlatformVersion = status.GetPlatformVersion() + consumerObj.Status.Client.OperatorVersion = status.GetOperatorVersion() - consumerObj := &ocsv1alpha1.StorageConsumer{} - consumerObj.Name = consumerName - consumerObj.Namespace = c.namespace - if err := c.client.Status().Patch(ctx, consumerObj, patch); err != nil { - return fmt.Errorf("Failed to patch Status.LastHeartbeat for StorageConsumer %v: %v", consumerName, err) + if err := c.client.Status().Update(ctx, consumerObj); err != nil { + return fmt.Errorf("Failed to patch Status for StorageConsumer %v: %v", consumerObj.Name, err) } - klog.Infof("successfully updated Status.LastHeartbeat for StorageConsumer %v", consumerName) + klog.Infof("successfully updated Status for StorageConsumer %v", consumerObj.Name) return nil } diff --git a/services/provider/server/consumer_test.go b/services/provider/server/consumer_test.go index 088d7acda7..b927c1e030 100644 --- a/services/provider/server/consumer_test.go +++ b/services/provider/server/consumer_test.go @@ -6,12 +6,12 @@ import ( api "github.com/red-hat-storage/ocs-operator/v4/api/v1" ocsv1alpha1 "github.com/red-hat-storage/ocs-operator/v4/api/v1alpha1" + providerClient "github.com/red-hat-storage/ocs-operator/v4/services/provider/client" rookCephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" ) @@ -47,7 +47,7 @@ var ( } ) -func newFakeClient(t *testing.T, obj ...runtime.Object) client.Client { +func newFakeClient(t *testing.T, obj ...client.Object) client.Client { scheme, err := api.SchemeBuilder.Build() assert.NoError(t, err, "unable to build scheme") @@ -60,12 +60,15 @@ func newFakeClient(t *testing.T, obj ...runtime.Object) client.Client { err = rookCephv1.AddToScheme(scheme) assert.NoError(t, err, "failed to add rookCephv1 scheme") - return fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(obj...).Build() + return fake.NewClientBuilder(). + WithScheme(scheme). + WithObjects(obj...). + WithStatusSubresource(obj...).Build() } func TestNewConsumerManager(t *testing.T) { ctx := context.TODO() - obj := []runtime.Object{} + obj := []client.Object{} // Test NewConsumerManager with no StorageConsumer resources client := newFakeClient(t) @@ -89,7 +92,7 @@ func TestNewConsumerManager(t *testing.T) { func TestCreateStorageConsumer(t *testing.T) { ctx := context.TODO() - obj := []runtime.Object{} + obj := []client.Object{} obj = append(obj, consumer1) client := newFakeClient(t, obj...) @@ -115,7 +118,7 @@ func TestCreateStorageConsumer(t *testing.T) { func TestDeleteStorageConsumer(t *testing.T) { ctx := context.TODO() - obj := []runtime.Object{} + obj := []client.Object{} obj = append(obj, consumer1) client := newFakeClient(t, obj...) @@ -142,7 +145,7 @@ func TestDeleteStorageConsumer(t *testing.T) { func TestGetStorageConsumer(t *testing.T) { ctx := context.TODO() - obj := []runtime.Object{} + obj := []client.Object{} obj = append(obj, consumer1) client := newFakeClient(t, obj...) @@ -158,3 +161,34 @@ func TestGetStorageConsumer(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "consumer1", consumer.Name) } + +func TestUpdateConsumerStatus(t *testing.T) { + ctx := context.TODO() + obj := []client.Object{} + + consumer := &ocsv1alpha1.StorageConsumer{} + consumer1.DeepCopyInto(consumer) + + // status should be preserved after update + consumer.Status.State = ocsv1alpha1.StorageConsumerStateReady + + obj = append(obj, consumer) + client := newFakeClient(t, obj...) + consumerManager, err := newConsumerManager(ctx, client, + testNamespace) + assert.NoError(t, err) + + // with fields + fields := providerClient.NewStorageClientStatus(). + SetPlatformVersion("1.0.0"). + SetOperatorVersion("1.0.0") + err = consumerManager.UpdateConsumerStatus(ctx, "uid1", fields) + assert.NoError(t, err) + + c1, err := consumerManager.Get(ctx, "uid1") + assert.NoError(t, err) + assert.NotEmpty(t, c1.Status.LastHeartbeat) + assert.Equal(t, fields.GetPlatformVersion(), c1.Status.Client.PlatformVersion) + assert.Equal(t, fields.GetOperatorVersion(), c1.Status.Client.OperatorVersion) + assert.Equal(t, c1.Status.State, ocsv1alpha1.StorageConsumerStateReady) +} diff --git a/services/provider/server/server.go b/services/provider/server/server.go index 261825a1fc..3067e76289 100644 --- a/services/provider/server/server.go +++ b/services/provider/server/server.go @@ -16,6 +16,7 @@ import ( "strings" "time" + "github.com/blang/semver/v4" "github.com/red-hat-storage/ocs-operator/v4/api/v1alpha1" ocsv1alpha1 "github.com/red-hat-storage/ocs-operator/v4/api/v1alpha1" controllers "github.com/red-hat-storage/ocs-operator/v4/controllers/storageconsumer" @@ -653,11 +654,20 @@ func (s *OCSProviderServer) GetStorageClassClaimConfig(ctx context.Context, req // ReportStatus rpc call to check if a consumer can reach to the provider. func (s *OCSProviderServer) ReportStatus(ctx context.Context, req *pb.ReportStatusRequest) (*pb.ReportStatusResponse, error) { // Update the status in storageConsumer CR - if err := s.consumerManager.UpdateStatusLastHeatbeat(ctx, req.StorageConsumerUUID); err != nil { + + if _, err := semver.Parse(req.ClientPlatformVersion); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "Malformed ClientPlatformVersion: %v", err) + } + + if _, err := semver.Parse(req.ClientOperatorVersion); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "Malformed ClientOperatorVersion: %v", err) + } + + if err := s.consumerManager.UpdateConsumerStatus(ctx, req.StorageConsumerUUID, req); err != nil { if kerrors.IsNotFound(err) { - return nil, status.Errorf(codes.NotFound, "Failed to update lastHeartbeat in the storageConsumer resource: %v", err) + return nil, status.Errorf(codes.NotFound, "Failed to update lastHeartbeat payload in the storageConsumer resource: %v", err) } - return nil, status.Errorf(codes.Internal, "Failed to update lastHeartbeat in the storageConsumer resource: %v", err) + return nil, status.Errorf(codes.Internal, "Failed to update lastHeartbeat payload in the storageConsumer resource: %v", err) } return &pb.ReportStatusResponse{}, nil diff --git a/services/provider/server/server_test.go b/services/provider/server/server_test.go index a263032a0c..3fcc80d17b 100644 --- a/services/provider/server/server_test.go +++ b/services/provider/server/server_test.go @@ -17,6 +17,7 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + crClient "sigs.k8s.io/controller-runtime/pkg/client" ) type externalResource struct { @@ -138,7 +139,7 @@ var ( func TestGetExternalResources(t *testing.T) { ctx := context.TODO() - objects := []runtime.Object{ + objects := []crClient.Object{ consumerResource, consumerResource1, consumerResource2, @@ -278,7 +279,7 @@ func TestGetExternalResources(t *testing.T) { assert.Nil(t, storageConRes) // When CephClient status is empty - objects = []runtime.Object{ + objects = []crClient.Object{ &rookCephv1.CephClient{}, } s := runtime.NewScheme() @@ -303,7 +304,7 @@ func TestGetExternalResources(t *testing.T) { // When CephClient status info is empty - objects = []runtime.Object{ + objects = []crClient.Object{ &rookCephv1.CephClient{}, } s = runtime.NewScheme() @@ -389,7 +390,7 @@ func TestOCSProviderServerStorageClassRequest(t *testing.T) { } ctx := context.TODO() - objects := []runtime.Object{ + objects := []crClient.Object{ consumerResource, claimResourceUnderDeletion, } @@ -455,7 +456,7 @@ func TestOCSProviderServerRevokeStorageClassClaim(t *testing.T) { } ctx := context.TODO() - objects := []runtime.Object{ + objects := []crClient.Object{ consumerResource, claimResource, } @@ -673,7 +674,7 @@ func TestOCSProviderServerGetStorageClassClaimConfig(t *testing.T) { ) ctx := context.TODO() - objects := []runtime.Object{ + objects := []crClient.Object{ consumerResource, blockPoolClaimResource, sharedFilesystemClaimResource,